1 PARTE I – Cuidados antes de começar a rodar os códigos no R

Pensar quais orientações são mais gerais e quais são importantes de acompanhar cada código.

1.1 Rstudio/Pacotes/versões/sistemas operacionais

Sobre os pacotes, seria bom ter uma listinha de ‘library’ no início de cada código? Talvez com uma breve explicação do que cada pacote faz, versão mínima… não sei.

OBS: essa tabela é uma referência para obtermos as versões dos pacotes ao final do desenvolvimento do script. Ela está automatizada, então quando terminarmos ele precisamos refaze-lo de forma que não gere mais mudança nas versões (tem que fazer a tabela na mão mesmo…).

# gerar informações sobre os pacotes carregados
info <- sessionInfo()

# gerar tabela com os pacotes e versões
tribble(
  ~Pacotes,                         ~Versão,
  version$language,                 version$version.string,
  info$otherPkgs$dplyr$Package,     info$otherPkgs$dplyr$Version,
  #info$otherPkgs$Distance$Package,  info$otherPkgs$Distance$Version,
  info$otherPkgs$DT$Package,        info$otherPkgs$DT$Version,
  info$otherPkgs$flextable$Package, info$otherPkgs$flextable$Version,
  info$otherPkgs$ggplot2$Package,     info$otherPkgs$ggplot2$Version,
  info$otherPkgs$lubridate$Package,     info$otherPkgs$lubridate$Version,
  info$otherPkgs$plotly$Package,    info$otherPkgs$plotly$Version,
  info$otherPkgs$readr$Package,     info$otherPkgs$readr$Version,
  info$otherPkgs$readxl$Package,     info$otherPkgs$readxl$Version,
  info$otherPkgs$stringr$Package,     info$otherPkgs$stringr$Version,
  info$otherPkgs$tibble$Package,    info$otherPkgs$tibble$Version,
  info$otherPkgs$tidyr$Package,     info$otherPkgs$tidyr$Version
) |> 
  qflextable() |> 
  set_caption(
    "Tabela xx - configuração de pacotes necessários e respectivas versões mínimas que devem ser utilizadas para reproduzir os códigos"
  )
Tabela xx - configuração de pacotes necessários e respectivas versões mínimas que devem ser utilizadas para reproduzir os códigos

Pacotes

Versão

R

R version 4.2.3 (2023-03-15 ucrt)

dplyr

1.1.0

DT

0.27

flextable

0.9.0

ggplot2

3.4.1

lubridate

1.9.2

plotly

4.10.1

readr

2.1.4

readxl

1.4.2

stringr

1.5.0

tibble

3.2.0

tidyr

1.3.0

1.2 Cuidados com a planilha .xlsx que será importada (para que mantenha o padrão da planilha de referência do ICMBio)

A primeira função que utilizaremos, carregar_dados_brutos_xlsx(), irá carregar a a planilha em formato excel, Planilha Oficial consolidada de Masto-aves 2014-21 Validada CEMAVE CPB CENAP.xlsx, e gerar automaticamente o arquivo dados_brutos.rds na pasta data-raw. A função seguinte a ser utilizada, carregar_dados_completos() que irá carregar o arquivo dados_brutos.rds. Essa função foi escrita para carrega os dados e operar uma série de transformações para devolve-lo no formato padronizado do programa DISTANCE para Windows. Portanto, para garantir a reprodutibilidade dos códigos produzidos em versões atualizadas da base de dados do Monitora, é importante tomar alguns cuidados.

O primeiro e mais importante cuidado é manter a consistência dos nomes das colunas em versões atualizadas da base de dados do Monitora. Além de carregar os dados, a função carregar_dados_completos() aplica uma série de transformações nas colunas. Seus nomes são alterados, e a essas são atribuídos tipos apropriados (data, caracter, fator, inteiro e numérico), linhas são eliminadas e novas colunas são gereadas. Para exemplificar, veja o código abaixo. Ele foi escrito para executar as primeiras transformações nos dados e constitui o corpo da função carregar_dados_filtrados().

# carregar a base de dados do Monitora
dados_brutos <- carregar_dados_brutos_xlsx()

# gerar o data.frame desejado reproduzindo as transformações realizadas pela função carregar_dados_completos()
dados_filtrados <- dados_brutos |>  
  # selecionar as colunas necessárias para as analises, padronizando os nomes para o formato DISTANCE
  dplyr::select(
    uc_code = CDUC,
    uc_name = `Local - Nome da Unidade de Conservacao`,
    ea_number = `Numero da Estacao Amostral`,
    ea_name = `Nome da EA`,
    season = `Estacao do ano`,
    sampling_day = `data da amostragem`,
    day_effort = `Esforco de amostragem tamanho da trilha (m)`,
    sp = `Especies validadas para analise do ICMBio`,
    distance = `distancia (m)     do animal em relacao a trilha`,
    group_size = `n de animais`,
    observadores = `nome dos observadores`
  ) |>
  # atribuir os tipos corretos às colunas e criar novas colunas
    dplyr::mutate(
      uc_category = stringi::stri_extract_first_words(
      uc_name
    ),
    # abrevia o nome das UCs
    uc_name_abv = forcats::lvls_revalue(
      uc_name,
      new_levels = c(
        "ETM", "EM", "EN", "ESGT", "FJ", "PCV", "PA", "PSBoc", "PSBod", "PSC",
        "PSM", "PSC", "PSD", "PSP", "PSO", "PPN", "PCO", "PI", "PJaú", "PJur",
        "PMR", "PS", "PV", "PCA", "PMT", "RG", "RJ", "RTap", "RU", "RG",
        "RTrom", "RAT", "RBA", "RCI", "RCM", "RRC", "RROP", "RIA", "RRA", "RTA"
      )
    ),
      # atribuir o tipo data à coluna sampling_day
      year = lubridate::year(
        sampling_day
      ),
      # atribuir o tipo fator às colunas do tipo caracter
      across(
        where(
          is.character
        ),
        as.factor
      ),
      # substituir separadores de nome por ","
      novo = stringr::str_replace_all(
        observadores, 
        " e ",
        ", "
      ),
      # substituir separadores de nome por ","
      novo = stringr::str_replace_all(
        novo, 
        " E ",
        ", "
      ),
      # substituir separadores de nome por ","
      novo = stringr::str_replace_all(
        novo, 
        "/",
        ", "
      ),
      # substituir separadores de nome por ","
      novo = stringr::str_replace_all(
        novo, 
        ";",
        ", "
      ),
      # substituir separadores de nome por ","
      novo = stringr::str_replace_all(
        novo, 
        " a ",
        ", "
      ) 
    ) |>
  # transformar os nomes dos observadores da coluna novo em colunas individuais
tidyr::separate_wider_delim(
  novo, 
  ",",
  names = c(
    "obs1", "obs2", "obs3", "obs4", "obs5", "obs6"
  ),
  too_few = "align_start"
) |> 
  # gerar uma nova coluna number_observers com o número total de observadores em um mesmo transecto
  dplyr::mutate(
    # se o valor da observação é diferente de NA, substituir por 1, se for NA, substituir por 0
    obs1 = ifelse(!is.na(obs1), 1, 0),
    obs2 = ifelse(!is.na(obs2), 1, 0),
    obs3 = ifelse(!is.na(obs3), 1, 0),
    obs4 = ifelse(!is.na(obs4), 1, 0),
    obs5 = ifelse(!is.na(obs5), 1, 0),
    obs6 = ifelse(!is.na(obs6), 1, 0),
    # gera nova coluna number_observers a partir da soma das colunas de observadores individuais
    number_observers = obs1 + obs2 + obs3 + obs4 + obs5 + obs6
  ) |> 
  # agrupar os dados pelas colunas ea_name e sampling_day
  group_by(
    ea_name, 
    sampling_day
  ) |> 
  # aninhar as observações agrupadas uem listas
  nest() |> 
  # completar com o valor correto as linhas vazias das da variável day_effort
  mutate(
    day_effort2 = purrr::map(
      data, \(.x) rep(
        .x$day_effort[
          !is.na(
            .x$day_effort
          )
        ][1]
      )
    )
  ) |> 
  # desanihar os dados
  unnest(
    c(
      data, 
      day_effort2
    )
  ) |> 
  # desagrupar os dados
  ungroup() |> 
  # selecionar as colunas desejadas e excluir as indesejadas
  select(
    tidyselect::starts_with(c("uc", "ea")),
    season,
    year,
    sampling_day,
    day_effort = day_effort2,
    sp:number_observers,
    -day_effort,
    -tidyselect::starts_with("obs")
  ) |>
  # filtrar os dados pela UC e espécie desejadas
    dplyr::filter(
      uc_name == "Resex Tapajos-Arapiuns",
      sp == "Dasyprocta croconota"
    ) |> 
  relocate(
    uc_category,
    .before = uc_name
  ) |> 
  relocate(
    uc_name_abv,
    .after = uc_name
  )

# gerar tabela dinâmica dos dados completos
dados_filtrados |> 
  slice(
    1:1000
  ) |> 
  datatable(
    filter = list(
      position = "top"
    )
  )

O trecho do código que vai da linha 103 a 115 serve selecionar apenas as colunas de interesse presente nos dados originais. Note que os nomes das planilhas originais constam nesse trecho. Caso o nome de qualque uma dessas colunas seja alterado a função deixará de funcionar.

Outro aspecto importante é a presença de observações não preenchidas (ex. células vazias) nos dados originais. A função foi desenha para resolver alguns problemas presentes nos dados originais. Por exemplo, nas o trecho do código das linhas xx a xx as observações vazias (NAs) são substituidas pelo valor correto na coluna day_effort. Essa correção continnuará sendo realizada em versões atualizadas dos dados do Monitora. Porém, se outras colunas além das que estão sendo corrigidas possuirem observações vazias os dados serão carregados e transformados, porém outras funções podem ter o seu funcionamento comprometido. Por exemplo… (funções de visualização e do pacote distance que podem naõ funcionar devido a ausência de observação)

Dentre todas as funções de carregamento de dados, apenas carregar_dados_brutos_xlsx() carrega a base de dados originais do Monitora, diretamente do diretório data-raw/monitora_masto_aves_2023_04_04.xlsx. Ao mesmo tempo que carrega e transforma os dados, essa função gera uma versão em um formato mais leve, .rds, no diretório data-raw (data-raw/monitora_masto_aves_2023_04_04.rds). A função seguinte no fluxo de trabalho carrega a base a partir dessa versão mais leve. Logo, sempre que houver atualizações no arquivo original de dados brutos é necessário iniciar a rotina de carregamento de dados necessariamente com a função carregar_dados_brutos_xlsx().

Outros cuidados…

Imaginando que a planilha de dados do monitora é algo dinâmico, que o nome das colunas pode ser editado…

1.3 Como abrir os arquivos: como salvar e descompactar a pasta. Abrir projeto

Um passo a passo de como salvar arquivo com os códigos e abrir.. Por exemplo, da forma como está é interessante descompactar a pasta e acessar os arquivos abrindo o projeto. Acho que isso pode mudar, dependendo de como viermos a entregar o produto final. Então podemos pensar nessa explicação no final.

1.4 Cuidados com diretório

Se a gente ainda precisar ter algum tipo de preocupação quanto a isso. Acho que não. Explicar a estrtura de diretórios do projeto.

1.5 Como rodar cada tipo de arquivo (markdown, shiny)

Não é trivial para quem não está acostumado… usar runApp, knit… até mesmo o shift+enter para rodar as linhas de comando uma a uma

2 PARTE II – Carregando os dados para o R

2.1 Dados brutos

Não precisa se assustar com a infnidade de códigos no exemplo acima. Serviu apenas para ilustrar que construir essas funções facilita a execução e a reprodutibilidade das análise dos dados do Monitora. Para cada tarefa existe uma função cujo funcionamento não necessita de preenchimento dos argumentos (embora seja possível fornece-los). Por traz das cortinas, as funções executam as tarafas necessárias para se obter o resultado desejado. Por exemplo, o mesmo resultado pode ser obtido utilizando apenas duas funções: carregar_dados_brutos_xlsx()e gerar_tabdin_dados_brutos().

# carregar dados brutos
dados_brutos <- carregar_dados_brutos_xlsx()

# gerar tabela dinamica dos dados brutos
gerar_tabdin_dados_brutos()

A função gerar_tabdin_dados_brutos(), por configuração, gera uma tabela dinâmica com 1000 linhas. Você pode controlar o número de linhas pelo argumento n_linhas =. Mas atenção! Ela não funcionará com um número superior a 4.500 linhas. Ao mudar a entrada de dados usando o argumento dados =, certifique-se de que seu número de linhas não exceda esse limite (ex. 4.500). INSERIR NOTA (após testar em máquinas diferentes) Esse valor pode varia de acordo com as configurações da sua máquina.

gerar_tabdin_dados_brutos(
  n_linhas = 1:4500
)

2.2 Dados completos

  • todas espécies/UCs – carrega_dados_1.Rmd Descrever o que os dados trazem e porque foram formatados dessa forma.
# carregar dados para o R
dados_completos <- carregar_dados_completos() 

# gerar tabela dinamica dos dados completos
gerar_tabdin_dados_completos()

2.3 Dados filtrados

  • por espécie/UC – carrega_dados_2.Rmd até o momento usado com o exemplo da cutia na Resex Tapajós-Arapiuns Descrever o que os dados trazem e porque foram formatados dessa forma.
# carregar dados para o R
dados_filtrados <- carregar_dados_filtrados()

# gerar tabela dinâmica dos dados fitrados
gerar_tabdin_dados_filtrados()

3 Parte III – Transformando dados para Distance

3.1 Dados completos

  • todas espécies/UCs – transformar_para_distanceR.Rmd
# transformar os dados para o formato do Distance
dados_distanceR_completo <- transformar_para_distanceR()

# gerar tabela dinamica dos dados no formato do distance do R
gerar_tabdin_dados_selecionados_distanceR()

Em princípio tudo certo até aqui.

# transformar os dados para o formato do Distance
dados_distance_r_covariaveis <- transformar_para_distanceR_covariaveis()

# tabdin de dados_distanceR_covariaveis
gerar_tabdin_dados_selecionados_distanceR_cov()

4 PARTE IV – Explorando e selecionando os dados para as análises

4.1 Selecionando os melhores modelos de estudo de acordo com os dados

Alguns cuidados devem ser tomados na preparação dos dados antes de serem analisados. O primeiro deles é o cuidado taxonômico. Para os dados do Monitora recomenda-se o uso dos dados das espécies validadas para análise pelo ICMBio, conforme o modelo utilizado para este fluxo de trabalho.

Alguns problemas com os dados, que podem trazer efeitos indesejados sobre as análises, podem ser detectados durante a fase de exploração. Ao selecionar os dados que serão analisados, é importante observar os seguintes aspectos:

Suficência Amostral - número de ocorrências por espécie:

Para que o método de análise por distância possa ser utilizado para estimativas baseadas em modelos, são recomendadas quantidades mínimas de registros de ocorrência e de transectos (Unidades Amostrais). Segundo BUCKLAND et. al. (2015), o número mínimo sugerido de animais ou grupos (ocorrências) é de 60 – 80 animais (ou grupos) quando a amostragem é feita pelo método dos transectos lineares. É possível utilizar números menores que estes para realizar as análises, porém deve-se ter o cuidado de verificar se as funções de detecção estão bem modeladas.

Para dados que serão estratificados (divididos em subconjuntos), estes números recomendados se aplicam a cada subconjunto. Isso ocorre porque as funções de detecção serão modeladas para cada estrato (p.ex.Region.Label), além da função de detecção para os dados globais. Um exemplo seria a análise dos dados, para uma mesma espécie, em diferentes UCs. Neste caso, o ideal seria ter a suficiência amostral mínima em cada UC para usar estratificação e estimar abundâncias e densidades em cada uma das UCs.

Suficiência amostral - réplicas e repetições

Para que haja uma boa cobertura da área de estudo e também uma boa quantidade de amostras independentes para estimar as abundâncias e densidades das espécies, é desejável um número satisfatório de réplicas. Segundo BUCKLAND et al. (2015), o número mínimo de réplicas para os transectos deve ser de 10-20, o que deve aumentar para espécies cujas populações são distribuídas em manchas.

De forma geral, para cada UC, o número de réplicas do Programa Monitora está abaixo do recomendado. O delinamento amostral atual para a compontente Florestal do subprograma Terrestre estabelece um número mínimo de três Estações Amostrais por Unidade de Conservação, o que é o caso de muitas UCs, chegando ao máximo de XX estações amostrais por UC. O baixo número de réplicas não chega a ser um problema na estimativa de densidade da Área Coberta pela amostragem (Covered Area), mas limita uma boa estimativa de densidade total para a Unidade de Conservação (Study Area).

Um outro aspecto relacionado a amostragem é o número de repetições por transecto. Segundo BUKLAND et al (2001, pg 79), as repetições devem ser incorporadas no esforço amostral multiplicando-se o número de vezes que o transecto foi percorrido pelo comprimento do transecto. A mesma recomendação é dada pelo Curso Online em Distance Sampling link. Esse ajuste no esforço amostral não deve ter grandes consequências para um baixo número de repetições. Porém, para números altos, leva a uma inflagem no tamanho da área coberta. Apenas para ilustar com um exemplo, para os dados da Resex Tapajós-Arapinuns, a Estação Amostral Boim foi percorrida durante 70 dias de amostragem. Isso significa que ajustando o comprimento do transecto de 5 km pelo número de repetições, o esforço amostral passou para 350 km. A área coberta aumentou em 70x, o que terá consequências sobre a estimativa densidade, que tenderá a ser subestimada. Além disso, o coeficiente de variação das estimativas de abundância e densidade também tenderá a aumentar pelo efeito das variações temporais entre as amostragens.

Uma forma de lidar com o excesso de amostragens repetidas é tratar as repetições como efeitos aleatórios dos modelos. Isso requer o uso de abordagens que vão além da amostragem por distância convecional, como o uso de Mixed Effect Models e Modelos Hierárquicos (p. ex. OEDEKOVEN et. al. 2013, 2014) Essas abordagens ainda não foram implementadas em nosso fluxo de trabalho até a presente versão e pretendemos testá-la até a oficina de capacitação.

Distribuição de frequência das ocorrências em relação à distância - efeitos indesejados

A distribuição ideal das frequências de ocorrência em relação à distância deve apresentar as seguintes características: a frequência de ocorrência deve ser maior próximo a zero, apresentar um longo platô (ombro), e decair gradativamente com o aumento da distância. Isso significa que os animais são totalmente detectáveis na distância zero, seguem sendo bem detectáveis a distâncias curtas e vão perdendo detectabilidade gradativamente com o aumento da distância.

Por isso, uma das etapas exploratórias é avaliar o histograma de frequências de ocorrência ao longo da distância em relação ao transecto (opção abaixo). Algumas distribuições indicam problemas nos dados que podem dificultar o ajuste das funções de detecção. Tais como:

Pico de ocorrências próximos à distância zero - spike near zero distance

Isso ocorre quando o número de observações próximos à distância zero é inflado em relação às demais distâncias. O efeito gráfico será um pico no histograma em zero ou próximo a zero, conforme o exemplo abaixo para os dados extraídos das cutias (Dasyprocta croconota) na Resex Tapajós-Arapiuns.

Distribuicao de Frequencia para Dasyprocta croconota na Resex Tapajos-Arapiuns

Este tipo de distribuição foi um padrão para as espécies com o maior número de ocorrência nos dados de aves e mamíferos do Programa Monitora Florestal. Acreditamos que existem dois fatores que podem estar causando esse acúmulo de dados em zero ou próximo a ele. Um deles seria um viés para avistamento de animais na trilha em ambientes de floresta. As trilhas podem atrair animais, e também oferecem melhor visibilidade em relação à floresta, especialmente se o sub-bosque for denso . O outro fator seria um possível arredondamento nas distâncias próximas a zero, pode gerar um “amontoamento” nos dados (heaping). Recomenda-se que valores de distância perpendicular nunca sejam arredondados.

Resposta evasiva das espécies em relação ao observador

Para espécies que podem apresentar resposta de deslocamento em relação ao observador, um dos efeitos indesejados nos dados é o deslocamento das maiores frequências de observações para as distâncias perpendiculares intermediárias.

parei por aqui… continua… ver melhor a estratégia de agrupar os dados

espécies com maior volume de dados total

  • maior volume de dados por UC – exploração_01.nb.html (acho que o .Rmd para gerar esse html não está na pasta Monitora). Eu tinha gostado bastante desse documento, com as tabelas dinâmicas. Talvez dê para selecionar as perguntas que são válidas de deixar/ tirar/ incluir. WWF - Projeto Monitora
  • espécies validadas

4.1.1 Exploração e seleção de dados

4.1.1.1 Aspectos relacionados ao número total de observações

Sistematizar os critérios utilizados para eliminar observações (linhas).

Pensar num esquema de árvore de decisão para se chegar ao subconjunto de dados que será analisados.

4.1.1.2 Quantas observações foram validadas para quais níveis taxonômicos?

Essas operações são realizadas sobre a tabela de dados dados_completos pois os dados que foram transformados para o formato do distace no R não possuem a coluna validation, necessária para essas opereações. Mais a frente o procedimento de como obter os dados selecionados e transformatos para o formato das análises será demonstrado.

# contar observações validadas ao nível de espécie
n_obs_validadas <- contar_n_obs_validadas()
n_obs_validadas

Foram selecionadas apenas as observações validadas ao nível de espécie, somando um total 19747 observações.

# gerar gráfico com número observações validadas para cada nível taxonômico
plotar_n_obs_validadas_interativo()

Filnalmente chegamos ao subconjunto dos dados que será utilizado para selecionar quais espécies serão analisadas.

# gerar tabela de dados selecionados
dados_selecionados <- carregar_dados_selecionados()

# gerar tabdin dados_selecionados 
gerar_tabdin_dados_selecionados()

4.1.1.3 Quantas unidades de conservação ao todo?

# contar número total de UC's 
n_ucs <- contar_n_uc()
n_ucs

Os dados são provenientes de 38 unidades de conservação ao todo.

4.1.1.4 Quantas espécies ao todo?

n_sp <- contar_n_sp()
n_sp

Até aqui temos dados para 165 espécies.

4.1.1.5 Quantas observações por unidade de conservação ao todo?

As UC’s foram filtradas de acordo com o número de observações permitir a visualização.

A função de contagem de UC’s gerou 40 UC’s, mas só há observações para 38. Lembrar de verificar isso.

# contar número de observações por UC
n_obs_uc <- contar_n_obs_uc()

# gerar tabdin
gerar_tabdin_n_obs_uc()

Adicionar o nome completo da UC na caixa interativa do gráfico. Identificar os plotes com subtítulos ex tentar adicionar título aos plotes Adicionar nomes das UCs nos 3 primeiros gáficos (descompartilhar eixo x)

# plotar o número de observações por UC
plotar_n_obs_uc_interativo()

4.1.1.6 Quantas observações para cada espécie?

Número de observações por espécie.

# contar total sp
n_sp <- contar_n_sp()
n_sp
# contar o número de observações por espécie
n_obs_sp <- contar_n_obs_sp()

# gerar tabela dinâmica com o número total de obsevações por espécie
gerar_tabdin_n_obs_sp()

Esse gráfico pode melhorar. Compartilhar o eixo x? Adicionar título ao eixo x…

# plotar o o número de observações por UC
plotar_n_obs_sp_interativo()

Tabela interativa para consulta do número de observações por espécie.

gerar_tabdin_n_obs_sp()

4.1.1.7 Quais e quantas observações para cada espécie por unidades de conservação?

# gerar tabela com o número de observações por espécie e por UC
n_obs_sp_uc <- contar_n_obs_sp_uc()
n_obs_sp_uc

Repensar esse gráfico… Talvez não seja necessário…

plotar_n_obs_sp_uc_interativo()

Gerar função tabela dinâmica.

gerar_tabdin_n_obs_sp_uc()

4.1.1.8 Quantas unidades de conservação foram amostradas em cada ano?

Gerar função para visualizar número de UCs amostradas em cada ano. Por agora não precisa Se der tempo incluir ao final.

Gerar função para tabela dinâmica.

gerar_tabdin_n_uc_ano()

4.1.1.9 Quais unidades de conservação foram amostradas em um maior número de anos?

Gerar gráfico com o número de anos em que cada UC foi amostrada. Por agora não precisa Se sobrar tempo acrescentar ao final.

Tabela

n_ano_uc <- contar_n_ano_uc()
n_ano_uc  

Gerar tabela dinamica.

gerar_tabdin_n_ano_uc()

4.1.1.10 Quantas observações foram realizadas por UC em cada ano?

n_obs_uc_ano <- contar_n_obs_uc_ano()
n_obs_uc_ano

Tabela interativa para consultar quantas observações foram realizadas por ano em cada UC

gerar_tabdin_n_obs_uc_ano()

4.1.1.11 Quantas observações para cada espécies por ano?

n_obs_sp_ano <- contar_n_obs_sp_ano()
n_obs_sp_ano

Tabela interativa para consultar quantas observações foram realizadas para cada espécie em cada ano

gerar_tabdin_n_obs_sp_ano()

4.1.1.12 Quantas observações para cada espécies por UC e por ano?

n_obs_sp_uc_ano <- contar_n_obs_sp_uc_ano()
n_obs_sp_uc_ano

Tabela interativa para consultar quantas observações foram realizadas para cada espécie em cada ano

gerar_tabdin_n_obs_sp_uc_ano()

4.1.1.13 Quantas observações para cada espécies por UC, por estação e por ano?

n_obs_sp_uc_estacao_ano <- contar_n_obs_sp_uc_estacao_ano()
n_obs_sp_uc_estacao_ano
gerar_tabdin_n_obs_sp_uc_estacao_ano()

4.1.1.14 Avaliando número de réplicas (Estações Amostrais) por UC

4.1.1.15 Selecionando melhores modelos de estudo considerando estratificação espacial/temporal – se há suficiência amostral (60-80 observações) por estrato

  • Possíveis estratificações espaciais – EAs/UCs

                      - UCs/Espécies
    • Possíveis estratificações temporais – Espécie/UC/Ano

4.1.1.16 Avaliando distância de truncamento

  • Gráficos de distribuição das frequências de ocorrência x distância perpendicular. Arquivos gráfico-exploratorio1.Rmd e gráfico-exploratorio2.Rmd (eu não sei como você fez para incluir aquela linha vermelha com o valor de w no gráfico exploratório 2, mas ficou legal)

4.1.1.17 Distribuição de distâncias

# gerar o gráfico exploratório da distribuição de distâncias perpendiculares para a espécies Dasyrocta croconota na Resex Tapajós-Arapiuns
fig <- dados_filtrados |>
  # excluir NA's da variável distance
  tidyr::drop_na(distance) |> 
  plotar_distribuicao_distancia_interativo()

fig

4.1.1.18 Avaliando covariáveis

– As covariáveis devem ser pensadas de acordo com o grupo taxonômico. Espécies que formam grupos devem ter a covariável ‘size’.

As estratégias de estratificação podem ser substituídas por covariáveis também (estratos espaciais/ ano)

Como covariável temporal, pode se pensar em usar, além do ano, a estação do ano (season), o horário do dia (para animais que variam a atividade). O horário do dia pode ser convertido em tempo após nascer do sol (como no exemplo). Mas para isso é necessário criar essa variável no dataset. E não é trivial porque precisa saber o horário de nascer do sol em cada dia/local para calcular.

ATENÇÃO: gerar gráficos distância x covariável

Exemplo de Gráficos de Marques et al. 2007

5 PARTE V – Ajustando os modelos

Esse trabalho do Marque et al. 2007 é uma boa referência de como usar as abordagens CDS global, CDS estratificada e MCDS.

Aqui, é possível testar alguns caminhos de modelos. A estratificação só faz sentido quando o volume de dados for grande. Ainda assim o uso de covariáveis pode substituir a estratificação. Pensar em como orientar o uso dessas abordagens

5.1 Modelos pela abordagem CDS – dados globais

  • função ds do Distance (argumentos básicos: truncation; key, adjustment, scale… estudar argumentos para ver se mais algum interessa)

5.2 Modelos pela abordagem CDS – dados estratificados

  • Aqui precisa ver direitinho os cuidados que precisa ter para ajustar as funções nos dados estratificados. Acho que faz em blocos. Vai aplicando os mesmos parâmetros para todos os estratos a cada modelo.

  • para cada estrato (espacial ou temporal) usar - função ds do Distance (argumentos básicos: truncation; key, adjustment, scale… estudar argumentos para ver se mais algum interessa)

5.3 Modelos pela abordagem MCDS – dados globais

Aqui não faz sentido estratificar

  • função ds do Distance (argumentos básicos: truncation; key, adjustment, scale… estudar argumentos para ver se mais algum interessa… para as covariáveis entra o argumento formula)

Dicas em Miller et al. 2019 sobre covariáveis (ver arquivo no driver).

6 PARTE VI – Avaliando os modelos

6.1 Ajuste dos modelos

  • função gof_ds

– para gerar Q-Q plots e testes associados

6.2 Selecionando modelos (AIC)

– função summarize_ds_models

DICAS EXTRAS DE MILLER et al. 2019

7 PARTE VII – PRODUTO FINAL

Criar expressões reativas

reactive() eventReactive()

observe() observeEvent()

reactiveVal() reactiveValues()

isolate()

8 Glossário

Descrever as variáveis (colunas), termos técnicos ao longo do texto…

LS0tDQp0aXRsZTogIkZsdXhvIGRlIHRyYWJhbGhvOiBkZSBwcm9kdWNhbyBkb3MgY29kaWdvcyBkb3MgZGFkb3MgZGUgQW1vc3RyYWdlbSBwb3IgRGlzdGFuY2lhIC0gUHJvZ3JhbWEgTW9uaXRvcmEgSUNNQmlvL01NQSINCmRhdGU6ICJDcmlhZG8gZW0gMzEgZGUgbWFyw6dvIGRlIDIwMjMsIGF0dWFsaXphZG8gZW0gYHIgZm9ybWF0KFN5cy50aW1lKCksICclZCBkZSAlQiBkZSAlWScpYCINCmF1dGhvcjogIkx1Y2lhbmEgRnVzaW5hdHRvIFxuIFZpdG9yIEJvcmdlcy1Kw7puaW9yIg0Kb3V0cHV0OiANCiAgaHRtbF9ub3RlYm9vazoNCiAgICB0b2M6IHRydWUNCiAgICB0b2NfZGVwdGg6IDUNCiAgICB0b2NfZmxvYXQ6IGZhbHNlDQogICAgbnVtYmVyX3NlY3Rpb246IHRydWUNCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cNCmVkaXRvcl9vcHRpb25zOiANCiAgbWFya2Rvd246IA0KICAgIHdyYXA6IDcyDQotLS0NCg0KYGBge3IgY29uZmlndXJhw6fDo28sIGluY2x1ZGU9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIG1lc3NhZ2U9RkFMU0V9DQojIGNhcnJlZ2FyIHBhY290ZXMNCmxpYnJhcnkoRGlzdGFuY2UpDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShEVCkNCmxpYnJhcnkoZmxleHRhYmxlKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShsdWJyaWRhdGUpDQpsaWJyYXJ5KHBsb3RseSkNCmxpYnJhcnkocmVhZHIpDQpsaWJyYXJ5KHJlYWR4bCkNCmxpYnJhcnkoc3RyaW5ncikNCmxpYnJhcnkodGliYmxlKQ0KbGlicmFyeSh0aWR5cikNCg0KIyBjYXJyZWdhciBhcyBmdW7Dp8O1ZXMgZGEgcGFzdGEgUg0KIyBjYXJyZWdhciBmdW7Dp8OjbyBjb3JyaWdpcl9kaXJldG9yaW8uUg0KIyBzb3VyY2UoDQojICAgcGFzdGUwKA0KIyAgICAgc3RyaW5ncjo6c3RyX3JlbW92ZSgNCiMgICAgICAgZ2V0d2QoKSwgDQojICAgICAgICdkb2MnDQojICAgICApLA0KIyAgICAgIlIvY29ycmlnaXJfZGlyZXRvcmlvLlIiDQojICAgKQ0KIyApIA0KIyANCiMgY2FycmVnYXIgZnVuw6fDo28gc2NyaXB0X2NhcnJlZ2FyX2Z1bsOnw7Vlc19wYXN0YV9yLlINCiMgc291cmNlKA0KIyAgIGNvcnJpZ2lyX2RpcmV0b3JpbygNCiMgICAgIGNvcnJpZ2UgPSAiUi9zY3JpcHRfY2FycmVnYXJfZnVuw6fDtWVzX3Bhc3RhX3IuUiINCiMgICApDQojICkNCnNvdXJjZShwYXN0ZTAoaGVyZTo6aGVyZSgpLCAiL1IvbWluaGFzX2Z1bmNvZXMuUiIpKQ0KDQpgYGANCg0KIyAqKlBBUlRFIEkgLS0gQ3VpZGFkb3MgYW50ZXMgZGUgY29tZcOnYXIgYSByb2RhciBvcyBjw7NkaWdvcyBubyBSKioNCg0KUGVuc2FyIHF1YWlzIG9yaWVudGHDp8O1ZXMgc8OjbyBtYWlzIGdlcmFpcyBlIHF1YWlzIHPDo28gaW1wb3J0YW50ZXMgZGUNCmFjb21wYW5oYXIgY2FkYSBjw7NkaWdvLg0KDQojIyAqKlJzdHVkaW8vUGFjb3Rlcy92ZXJzw7Vlcy9zaXN0ZW1hcyBvcGVyYWNpb25haXMqKg0KDQpTb2JyZSBvcyBwYWNvdGVzLCBzZXJpYSBib20gdGVyIHVtYSBsaXN0aW5oYSBkZSAnbGlicmFyeScgbm8gaW7DrWNpbyBkZQ0KY2FkYSBjw7NkaWdvPyBUYWx2ZXogY29tIHVtYSBicmV2ZSBleHBsaWNhw6fDo28gZG8gcXVlIGNhZGEgcGFjb3RlIGZheiwNCnZlcnPDo28gbcOtbmltYS4uLiBuw6NvIHNlaS4NCg0KKipPQlMqKjogZXNzYSB0YWJlbGEgw6kgdW1hIHJlZmVyw6puY2lhIHBhcmEgb2J0ZXJtb3MgYXMgdmVyc8O1ZXMgZG9zDQpwYWNvdGVzIGFvIGZpbmFsIGRvIGRlc2Vudm9sdmltZW50byBkbyBzY3JpcHQuIEVsYSBlc3TDoSBhdXRvbWF0aXphZGEsDQplbnTDo28gcXVhbmRvIHRlcm1pbmFybW9zIGVsZSBwcmVjaXNhbW9zIHJlZmF6ZS1sbyBkZSBmb3JtYSBxdWUgbsOjbyBnZXJlDQptYWlzIG11ZGFuw6dhIG5hcyB2ZXJzw7VlcyAodGVtIHF1ZSBmYXplciBhIHRhYmVsYSBuYSBtw6NvIG1lc21vLi4uKS4NCg0KYGBge3J9DQojIGdlcmFyIGluZm9ybWHDp8O1ZXMgc29icmUgb3MgcGFjb3RlcyBjYXJyZWdhZG9zDQppbmZvIDwtIHNlc3Npb25JbmZvKCkNCg0KIyBnZXJhciB0YWJlbGEgY29tIG9zIHBhY290ZXMgZSB2ZXJzw7Vlcw0KdHJpYmJsZSgNCiAgflBhY290ZXMsICAgICAgICAgICAgICAgICAgICAgICAgIH5WZXJzw6NvLA0KICB2ZXJzaW9uJGxhbmd1YWdlLCAgICAgICAgICAgICAgICAgdmVyc2lvbiR2ZXJzaW9uLnN0cmluZywNCiAgaW5mbyRvdGhlclBrZ3MkZHBseXIkUGFja2FnZSwgICAgIGluZm8kb3RoZXJQa2dzJGRwbHlyJFZlcnNpb24sDQogICNpbmZvJG90aGVyUGtncyREaXN0YW5jZSRQYWNrYWdlLCAgaW5mbyRvdGhlclBrZ3MkRGlzdGFuY2UkVmVyc2lvbiwNCiAgaW5mbyRvdGhlclBrZ3MkRFQkUGFja2FnZSwgICAgICAgIGluZm8kb3RoZXJQa2dzJERUJFZlcnNpb24sDQogIGluZm8kb3RoZXJQa2dzJGZsZXh0YWJsZSRQYWNrYWdlLCBpbmZvJG90aGVyUGtncyRmbGV4dGFibGUkVmVyc2lvbiwNCiAgaW5mbyRvdGhlclBrZ3MkZ2dwbG90MiRQYWNrYWdlLCAgICAgaW5mbyRvdGhlclBrZ3MkZ2dwbG90MiRWZXJzaW9uLA0KICBpbmZvJG90aGVyUGtncyRsdWJyaWRhdGUkUGFja2FnZSwgICAgIGluZm8kb3RoZXJQa2dzJGx1YnJpZGF0ZSRWZXJzaW9uLA0KICBpbmZvJG90aGVyUGtncyRwbG90bHkkUGFja2FnZSwgICAgaW5mbyRvdGhlclBrZ3MkcGxvdGx5JFZlcnNpb24sDQogIGluZm8kb3RoZXJQa2dzJHJlYWRyJFBhY2thZ2UsICAgICBpbmZvJG90aGVyUGtncyRyZWFkciRWZXJzaW9uLA0KICBpbmZvJG90aGVyUGtncyRyZWFkeGwkUGFja2FnZSwgICAgIGluZm8kb3RoZXJQa2dzJHJlYWR4bCRWZXJzaW9uLA0KICBpbmZvJG90aGVyUGtncyRzdHJpbmdyJFBhY2thZ2UsICAgICBpbmZvJG90aGVyUGtncyRzdHJpbmdyJFZlcnNpb24sDQogIGluZm8kb3RoZXJQa2dzJHRpYmJsZSRQYWNrYWdlLCAgICBpbmZvJG90aGVyUGtncyR0aWJibGUkVmVyc2lvbiwNCiAgaW5mbyRvdGhlclBrZ3MkdGlkeXIkUGFja2FnZSwgICAgIGluZm8kb3RoZXJQa2dzJHRpZHlyJFZlcnNpb24NCikgfD4gDQogIHFmbGV4dGFibGUoKSB8PiANCiAgc2V0X2NhcHRpb24oDQogICAgIlRhYmVsYSB4eCAtIGNvbmZpZ3VyYcOnw6NvIGRlIHBhY290ZXMgbmVjZXNzw6FyaW9zIGUgcmVzcGVjdGl2YXMgdmVyc8O1ZXMgbcOtbmltYXMgcXVlIGRldmVtIHNlciB1dGlsaXphZGFzIHBhcmEgcmVwcm9kdXppciBvcyBjw7NkaWdvcyINCiAgKQ0KYGBgDQoNCiMjICoqQ3VpZGFkb3MgY29tIGEgcGxhbmlsaGEgLnhsc3ggcXVlIHNlcsOhIGltcG9ydGFkYSAocGFyYSBxdWUgbWFudGVuaGEgbyBwYWRyw6NvIGRhIHBsYW5pbGhhIGRlIHJlZmVyw6puY2lhIGRvIElDTUJpbykqKg0KDQpBIHByaW1laXJhIGZ1bsOnw6NvIHF1ZSB1dGlsaXphcmVtb3MsIGBjYXJyZWdhcl9kYWRvc19icnV0b3NfeGxzeCgpYCwgaXLDoQ0KY2FycmVnYXIgYSBhIHBsYW5pbGhhIGVtIGZvcm1hdG8gZXhjZWwsDQpgUGxhbmlsaGEgT2ZpY2lhbCBjb25zb2xpZGFkYSBkZSBNYXN0by1hdmVzIDIwMTQtMjEgVmFsaWRhZGEgQ0VNQVZFIENQQiBDRU5BUC54bHN4YCwNCmUgZ2VyYXIgYXV0b21hdGljYW1lbnRlIG8gYXJxdWl2byBgZGFkb3NfYnJ1dG9zLnJkc2AgbmEgcGFzdGENCmBkYXRhLXJhd2AuIEEgZnVuw6fDo28gc2VndWludGUgYSBzZXIgdXRpbGl6YWRhLA0KYGNhcnJlZ2FyX2RhZG9zX2NvbXBsZXRvcygpYCBxdWUgaXLDoSBjYXJyZWdhciBvIGFycXVpdm8NCmBkYWRvc19icnV0b3MucmRzYC4gRXNzYSBmdW7Dp8OjbyBmb2kgZXNjcml0YSBwYXJhIGNhcnJlZ2Egb3MgZGFkb3MgZQ0Kb3BlcmFyIHVtYSBzw6lyaWUgZGUgdHJhbnNmb3JtYcOnw7VlcyBwYXJhIGRldm9sdmUtbG8gbm8gZm9ybWF0bw0KcGFkcm9uaXphZG8gZG8gcHJvZ3JhbWEgKipESVNUQU5DRSoqIHBhcmEgV2luZG93cy4gUG9ydGFudG8sIHBhcmENCmdhcmFudGlyIGEgcmVwcm9kdXRpYmlsaWRhZGUgZG9zIGPDs2RpZ29zIHByb2R1emlkb3MgZW0gdmVyc8O1ZXMNCmF0dWFsaXphZGFzIGRhIGJhc2UgZGUgZGFkb3MgZG8gTW9uaXRvcmEsIMOpIGltcG9ydGFudGUgdG9tYXIgYWxndW5zDQpjdWlkYWRvcy4NCg0KTyBwcmltZWlybyBlIG1haXMgaW1wb3J0YW50ZSBjdWlkYWRvIMOpICoqbWFudGVyIGEgY29uc2lzdMOqbmNpYSBkb3Mgbm9tZXMNCmRhcyBjb2x1bmFzKiogZW0gdmVyc8O1ZXMgYXR1YWxpemFkYXMgZGEgYmFzZSBkZSBkYWRvcyBkbyBNb25pdG9yYS4gQWzDqW0NCmRlIGNhcnJlZ2FyIG9zIGRhZG9zLCBhIGZ1bsOnw6NvIGBjYXJyZWdhcl9kYWRvc19jb21wbGV0b3MoKWAgYXBsaWNhIHVtYQ0Kc8OpcmllIGRlIHRyYW5zZm9ybWHDp8O1ZXMgbmFzIGNvbHVuYXMuIFNldXMgbm9tZXMgc8OjbyBhbHRlcmFkb3MsIGUgYSBlc3Nhcw0Kc8OjbyBhdHJpYnXDrWRvcyB0aXBvcyBhcHJvcHJpYWRvcyAoZGF0YSwgY2FyYWN0ZXIsIGZhdG9yLCBpbnRlaXJvIGUNCm51bcOpcmljbyksIGxpbmhhcyBzw6NvIGVsaW1pbmFkYXMgZSBub3ZhcyBjb2x1bmFzIHPDo28gZ2VyZWFkYXMuIFBhcmENCmV4ZW1wbGlmaWNhciwgdmVqYSBvIGPDs2RpZ28gYWJhaXhvLiBFbGUgZm9pIGVzY3JpdG8gcGFyYSBleGVjdXRhciBhcw0KcHJpbWVpcmFzIHRyYW5zZm9ybWHDp8O1ZXMgbm9zIGRhZG9zIGUgY29uc3RpdHVpIG8gY29ycG8gZGEgZnVuw6fDo28NCmBjYXJyZWdhcl9kYWRvc19maWx0cmFkb3MoKWAuDQoNCmBgYHtyfQ0KIyBjYXJyZWdhciBhIGJhc2UgZGUgZGFkb3MgZG8gTW9uaXRvcmENCmRhZG9zX2JydXRvcyA8LSBjYXJyZWdhcl9kYWRvc19icnV0b3NfeGxzeCgpDQoNCiMgZ2VyYXIgbyBkYXRhLmZyYW1lIGRlc2VqYWRvIHJlcHJvZHV6aW5kbyBhcyB0cmFuc2Zvcm1hw6fDtWVzIHJlYWxpemFkYXMgcGVsYSBmdW7Dp8OjbyBjYXJyZWdhcl9kYWRvc19jb21wbGV0b3MoKQ0KZGFkb3NfZmlsdHJhZG9zIDwtIGRhZG9zX2JydXRvcyB8PiAgDQogICMgc2VsZWNpb25hciBhcyBjb2x1bmFzIG5lY2Vzc8OhcmlhcyBwYXJhIGFzIGFuYWxpc2VzLCBwYWRyb25pemFuZG8gb3Mgbm9tZXMgcGFyYSBvIGZvcm1hdG8gRElTVEFOQ0UNCiAgZHBseXI6OnNlbGVjdCgNCiAgICB1Y19jb2RlID0gQ0RVQywNCiAgICB1Y19uYW1lID0gYExvY2FsIC0gTm9tZSBkYSBVbmlkYWRlIGRlIENvbnNlcnZhY2FvYCwNCiAgICBlYV9udW1iZXIgPSBgTnVtZXJvIGRhIEVzdGFjYW8gQW1vc3RyYWxgLA0KICAgIGVhX25hbWUgPSBgTm9tZSBkYSBFQWAsDQogICAgc2Vhc29uID0gYEVzdGFjYW8gZG8gYW5vYCwNCiAgICBzYW1wbGluZ19kYXkgPSBgZGF0YSBkYSBhbW9zdHJhZ2VtYCwNCiAgICBkYXlfZWZmb3J0ID0gYEVzZm9yY28gZGUgYW1vc3RyYWdlbSB0YW1hbmhvIGRhIHRyaWxoYSAobSlgLA0KICAgIHNwID0gYEVzcGVjaWVzIHZhbGlkYWRhcyBwYXJhIGFuYWxpc2UgZG8gSUNNQmlvYCwNCiAgICBkaXN0YW5jZSA9IGBkaXN0YW5jaWEgKG0pICAgICBkbyBhbmltYWwgZW0gcmVsYWNhbyBhIHRyaWxoYWAsDQogICAgZ3JvdXBfc2l6ZSA9IGBuIGRlIGFuaW1haXNgLA0KICAgIG9ic2VydmFkb3JlcyA9IGBub21lIGRvcyBvYnNlcnZhZG9yZXNgDQogICkgfD4NCiAgIyBhdHJpYnVpciBvcyB0aXBvcyBjb3JyZXRvcyDDoHMgY29sdW5hcyBlIGNyaWFyIG5vdmFzIGNvbHVuYXMNCiAgICBkcGx5cjo6bXV0YXRlKA0KICAgICAgdWNfY2F0ZWdvcnkgPSBzdHJpbmdpOjpzdHJpX2V4dHJhY3RfZmlyc3Rfd29yZHMoDQogICAgICB1Y19uYW1lDQogICAgKSwNCiAgICAjIGFicmV2aWEgbyBub21lIGRhcyBVQ3MNCiAgICB1Y19uYW1lX2FidiA9IGZvcmNhdHM6Omx2bHNfcmV2YWx1ZSgNCiAgICAgIHVjX25hbWUsDQogICAgICBuZXdfbGV2ZWxzID0gYygNCiAgICAgICAgIkVUTSIsICJFTSIsICJFTiIsICJFU0dUIiwgIkZKIiwgIlBDViIsICJQQSIsICJQU0JvYyIsICJQU0JvZCIsICJQU0MiLA0KICAgICAgICAiUFNNIiwgIlBTQyIsICJQU0QiLCAiUFNQIiwgIlBTTyIsICJQUE4iLCAiUENPIiwgIlBJIiwgIlBKYcO6IiwgIlBKdXIiLA0KICAgICAgICAiUE1SIiwgIlBTIiwgIlBWIiwgIlBDQSIsICJQTVQiLCAiUkciLCAiUkoiLCAiUlRhcCIsICJSVSIsICJSRyIsDQogICAgICAgICJSVHJvbSIsICJSQVQiLCAiUkJBIiwgIlJDSSIsICJSQ00iLCAiUlJDIiwgIlJST1AiLCAiUklBIiwgIlJSQSIsICJSVEEiDQogICAgICApDQogICAgKSwNCiAgICAgICMgYXRyaWJ1aXIgbyB0aXBvIGRhdGEgw6AgY29sdW5hIHNhbXBsaW5nX2RheQ0KICAgICAgeWVhciA9IGx1YnJpZGF0ZTo6eWVhcigNCiAgICAgICAgc2FtcGxpbmdfZGF5DQogICAgICApLA0KICAgICAgIyBhdHJpYnVpciBvIHRpcG8gZmF0b3Igw6BzIGNvbHVuYXMgZG8gdGlwbyBjYXJhY3Rlcg0KICAgICAgYWNyb3NzKA0KICAgICAgICB3aGVyZSgNCiAgICAgICAgICBpcy5jaGFyYWN0ZXINCiAgICAgICAgKSwNCiAgICAgICAgYXMuZmFjdG9yDQogICAgICApLA0KICAgICAgIyBzdWJzdGl0dWlyIHNlcGFyYWRvcmVzIGRlIG5vbWUgcG9yICIsIg0KICAgICAgbm92byA9IHN0cmluZ3I6OnN0cl9yZXBsYWNlX2FsbCgNCiAgICAgICAgb2JzZXJ2YWRvcmVzLCANCiAgICAgICAgIiBlICIsDQogICAgICAgICIsICINCiAgICAgICksDQogICAgICAjIHN1YnN0aXR1aXIgc2VwYXJhZG9yZXMgZGUgbm9tZSBwb3IgIiwiDQogICAgICBub3ZvID0gc3RyaW5ncjo6c3RyX3JlcGxhY2VfYWxsKA0KICAgICAgICBub3ZvLCANCiAgICAgICAgIiBFICIsDQogICAgICAgICIsICINCiAgICAgICksDQogICAgICAjIHN1YnN0aXR1aXIgc2VwYXJhZG9yZXMgZGUgbm9tZSBwb3IgIiwiDQogICAgICBub3ZvID0gc3RyaW5ncjo6c3RyX3JlcGxhY2VfYWxsKA0KICAgICAgICBub3ZvLCANCiAgICAgICAgIi8iLA0KICAgICAgICAiLCAiDQogICAgICApLA0KICAgICAgIyBzdWJzdGl0dWlyIHNlcGFyYWRvcmVzIGRlIG5vbWUgcG9yICIsIg0KICAgICAgbm92byA9IHN0cmluZ3I6OnN0cl9yZXBsYWNlX2FsbCgNCiAgICAgICAgbm92bywgDQogICAgICAgICI7IiwNCiAgICAgICAgIiwgIg0KICAgICAgKSwNCiAgICAgICMgc3Vic3RpdHVpciBzZXBhcmFkb3JlcyBkZSBub21lIHBvciAiLCINCiAgICAgIG5vdm8gPSBzdHJpbmdyOjpzdHJfcmVwbGFjZV9hbGwoDQogICAgICAgIG5vdm8sIA0KICAgICAgICAiIGEgIiwNCiAgICAgICAgIiwgIg0KICAgICAgKSANCiAgICApIHw+DQogICMgdHJhbnNmb3JtYXIgb3Mgbm9tZXMgZG9zIG9ic2VydmFkb3JlcyBkYSBjb2x1bmEgbm92byBlbSBjb2x1bmFzIGluZGl2aWR1YWlzDQp0aWR5cjo6c2VwYXJhdGVfd2lkZXJfZGVsaW0oDQogIG5vdm8sIA0KICAiLCIsDQogIG5hbWVzID0gYygNCiAgICAib2JzMSIsICJvYnMyIiwgIm9iczMiLCAib2JzNCIsICJvYnM1IiwgIm9iczYiDQogICksDQogIHRvb19mZXcgPSAiYWxpZ25fc3RhcnQiDQopIHw+IA0KICAjIGdlcmFyIHVtYSBub3ZhIGNvbHVuYSBudW1iZXJfb2JzZXJ2ZXJzIGNvbSBvIG7Dum1lcm8gdG90YWwgZGUgb2JzZXJ2YWRvcmVzIGVtIHVtIG1lc21vIHRyYW5zZWN0bw0KICBkcGx5cjo6bXV0YXRlKA0KICAgICMgc2UgbyB2YWxvciBkYSBvYnNlcnZhw6fDo28gw6kgZGlmZXJlbnRlIGRlIE5BLCBzdWJzdGl0dWlyIHBvciAxLCBzZSBmb3IgTkEsIHN1YnN0aXR1aXIgcG9yIDANCiAgICBvYnMxID0gaWZlbHNlKCFpcy5uYShvYnMxKSwgMSwgMCksDQogICAgb2JzMiA9IGlmZWxzZSghaXMubmEob2JzMiksIDEsIDApLA0KICAgIG9iczMgPSBpZmVsc2UoIWlzLm5hKG9iczMpLCAxLCAwKSwNCiAgICBvYnM0ID0gaWZlbHNlKCFpcy5uYShvYnM0KSwgMSwgMCksDQogICAgb2JzNSA9IGlmZWxzZSghaXMubmEob2JzNSksIDEsIDApLA0KICAgIG9iczYgPSBpZmVsc2UoIWlzLm5hKG9iczYpLCAxLCAwKSwNCiAgICAjIGdlcmEgbm92YSBjb2x1bmEgbnVtYmVyX29ic2VydmVycyBhIHBhcnRpciBkYSBzb21hIGRhcyBjb2x1bmFzIGRlIG9ic2VydmFkb3JlcyBpbmRpdmlkdWFpcw0KICAgIG51bWJlcl9vYnNlcnZlcnMgPSBvYnMxICsgb2JzMiArIG9iczMgKyBvYnM0ICsgb2JzNSArIG9iczYNCiAgKSB8PiANCiAgIyBhZ3J1cGFyIG9zIGRhZG9zIHBlbGFzIGNvbHVuYXMgZWFfbmFtZSBlIHNhbXBsaW5nX2RheQ0KICBncm91cF9ieSgNCiAgICBlYV9uYW1lLCANCiAgICBzYW1wbGluZ19kYXkNCiAgKSB8PiANCiAgIyBhbmluaGFyIGFzIG9ic2VydmHDp8O1ZXMgYWdydXBhZGFzIHVlbSBsaXN0YXMNCiAgbmVzdCgpIHw+IA0KICAjIGNvbXBsZXRhciBjb20gbyB2YWxvciBjb3JyZXRvIGFzIGxpbmhhcyB2YXppYXMgZGFzIGRhIHZhcmnDoXZlbCBkYXlfZWZmb3J0DQogIG11dGF0ZSgNCiAgICBkYXlfZWZmb3J0MiA9IHB1cnJyOjptYXAoDQogICAgICBkYXRhLCBcKC54KSByZXAoDQogICAgICAgIC54JGRheV9lZmZvcnRbDQogICAgICAgICAgIWlzLm5hKA0KICAgICAgICAgICAgLngkZGF5X2VmZm9ydA0KICAgICAgICAgICkNCiAgICAgICAgXVsxXQ0KICAgICAgKQ0KICAgICkNCiAgKSB8PiANCiAgIyBkZXNhbmloYXIgb3MgZGFkb3MNCiAgdW5uZXN0KA0KICAgIGMoDQogICAgICBkYXRhLCANCiAgICAgIGRheV9lZmZvcnQyDQogICAgKQ0KICApIHw+IA0KICAjIGRlc2FncnVwYXIgb3MgZGFkb3MNCiAgdW5ncm91cCgpIHw+IA0KICAjIHNlbGVjaW9uYXIgYXMgY29sdW5hcyBkZXNlamFkYXMgZSBleGNsdWlyIGFzIGluZGVzZWphZGFzDQogIHNlbGVjdCgNCiAgICB0aWR5c2VsZWN0OjpzdGFydHNfd2l0aChjKCJ1YyIsICJlYSIpKSwNCiAgICBzZWFzb24sDQogICAgeWVhciwNCiAgICBzYW1wbGluZ19kYXksDQogICAgZGF5X2VmZm9ydCA9IGRheV9lZmZvcnQyLA0KICAgIHNwOm51bWJlcl9vYnNlcnZlcnMsDQogICAgLWRheV9lZmZvcnQsDQogICAgLXRpZHlzZWxlY3Q6OnN0YXJ0c193aXRoKCJvYnMiKQ0KICApIHw+DQogICMgZmlsdHJhciBvcyBkYWRvcyBwZWxhIFVDIGUgZXNww6ljaWUgZGVzZWphZGFzDQogICAgZHBseXI6OmZpbHRlcigNCiAgICAgIHVjX25hbWUgPT0gIlJlc2V4IFRhcGFqb3MtQXJhcGl1bnMiLA0KICAgICAgc3AgPT0gIkRhc3lwcm9jdGEgY3JvY29ub3RhIg0KICAgICkgfD4gDQogIHJlbG9jYXRlKA0KICAgIHVjX2NhdGVnb3J5LA0KICAgIC5iZWZvcmUgPSB1Y19uYW1lDQogICkgfD4gDQogIHJlbG9jYXRlKA0KICAgIHVjX25hbWVfYWJ2LA0KICAgIC5hZnRlciA9IHVjX25hbWUNCiAgKQ0KDQojIGdlcmFyIHRhYmVsYSBkaW7Dom1pY2EgZG9zIGRhZG9zIGNvbXBsZXRvcw0KZGFkb3NfZmlsdHJhZG9zIHw+IA0KICBzbGljZSgNCiAgICAxOjEwMDANCiAgKSB8PiANCiAgZGF0YXRhYmxlKA0KICAgIGZpbHRlciA9IGxpc3QoDQogICAgICBwb3NpdGlvbiA9ICJ0b3AiDQogICAgKQ0KICApDQpgYGANCg0KTyB0cmVjaG8gZG8gY8OzZGlnbyBxdWUgdmFpIGRhIGxpbmhhIDEwMyBhIDExNSBzZXJ2ZSBzZWxlY2lvbmFyIGFwZW5hcyBhcw0KY29sdW5hcyBkZSBpbnRlcmVzc2UgcHJlc2VudGUgbm9zIGRhZG9zIG9yaWdpbmFpcy4gTm90ZSBxdWUgb3Mgbm9tZXMgZGFzDQpwbGFuaWxoYXMgb3JpZ2luYWlzIGNvbnN0YW0gbmVzc2UgdHJlY2hvLiBDYXNvIG8gbm9tZSBkZSBxdWFscXVlIHVtYQ0KZGVzc2FzIGNvbHVuYXMgc2VqYSBhbHRlcmFkbyBhIGZ1bsOnw6NvIGRlaXhhcsOhIGRlIGZ1bmNpb25hci4NCg0KT3V0cm8gYXNwZWN0byBpbXBvcnRhbnRlIMOpIGEgcHJlc2Vuw6dhIGRlIG9ic2VydmHDp8O1ZXMgbsOjbyBwcmVlbmNoaWRhcw0KKGV4LiBjw6lsdWxhcyB2YXppYXMpIG5vcyBkYWRvcyBvcmlnaW5haXMuIEEgZnVuw6fDo28gZm9pIGRlc2VuaGEgcGFyYQ0KcmVzb2x2ZXIgYWxndW5zIHByb2JsZW1hcyBwcmVzZW50ZXMgbm9zIGRhZG9zIG9yaWdpbmFpcy4gUG9yIGV4ZW1wbG8sDQpuYXMgbyB0cmVjaG8gZG8gY8OzZGlnbyBkYXMgbGluaGFzIHh4IGEgeHggYXMgb2JzZXJ2YcOnw7VlcyB2YXppYXMgKGBOQWBzKQ0Kc8OjbyBzdWJzdGl0dWlkYXMgcGVsbyB2YWxvciBjb3JyZXRvIG5hIGNvbHVuYSBgZGF5X2VmZm9ydGAuIEVzc2ENCmNvcnJlw6fDo28gY29udGlubnVhcsOhIHNlbmRvIHJlYWxpemFkYSBlbSB2ZXJzw7VlcyBhdHVhbGl6YWRhcyBkb3MgZGFkb3MgZG8NCk1vbml0b3JhLiBQb3LDqW0sIHNlIG91dHJhcyBjb2x1bmFzIGFsw6ltIGRhcyBxdWUgZXN0w6NvIHNlbmRvIGNvcnJpZ2lkYXMNCnBvc3N1aXJlbSBvYnNlcnZhw6fDtWVzIHZhemlhcyBvcyBkYWRvcyBzZXLDo28gY2FycmVnYWRvcyBlIHRyYW5zZm9ybWFkb3MsDQpwb3LDqW0gb3V0cmFzIGZ1bsOnw7VlcyBwb2RlbSB0ZXIgbyBzZXUgZnVuY2lvbmFtZW50byBjb21wcm9tZXRpZG8uIFBvcg0KZXhlbXBsby4uLiAoZnVuw6fDtWVzIGRlIHZpc3VhbGl6YcOnw6NvIGUgZG8gcGFjb3RlIGRpc3RhbmNlIHF1ZSBwb2RlbSBuYcO1DQpmdW5jaW9uYXIgZGV2aWRvIGEgYXVzw6puY2lhIGRlIG9ic2VydmHDp8OjbykNCg0KRGVudHJlIHRvZGFzIGFzIGZ1bsOnw7VlcyBkZSBjYXJyZWdhbWVudG8gZGUgZGFkb3MsIGFwZW5hcw0KYGNhcnJlZ2FyX2RhZG9zX2JydXRvc194bHN4KClgIGNhcnJlZ2EgYSBiYXNlIGRlIGRhZG9zIG9yaWdpbmFpcyBkbw0KTW9uaXRvcmEsIGRpcmV0YW1lbnRlIGRvIGRpcmV0w7NyaW8NCmBkYXRhLXJhdy9tb25pdG9yYV9tYXN0b19hdmVzXzIwMjNfMDRfMDQueGxzeGAuIEFvIG1lc21vIHRlbXBvIHF1ZQ0KY2FycmVnYSBlIHRyYW5zZm9ybWEgb3MgZGFkb3MsIGVzc2EgZnVuw6fDo28gZ2VyYSB1bWEgdmVyc8OjbyBlbSB1bSBmb3JtYXRvDQptYWlzIGxldmUsIGAucmRzYCwgbm8gZGlyZXTDs3JpbyBgZGF0YS1yYXdgDQooYGRhdGEtcmF3L21vbml0b3JhX21hc3RvX2F2ZXNfMjAyM18wNF8wNC5yZHNgKS4gQSBmdW7Dp8OjbyBzZWd1aW50ZSBubw0KZmx1eG8gZGUgdHJhYmFsaG8gY2FycmVnYSBhIGJhc2UgYSBwYXJ0aXIgZGVzc2EgdmVyc8OjbyBtYWlzIGxldmUuIExvZ28sDQpzZW1wcmUgcXVlIGhvdXZlciBhdHVhbGl6YcOnw7VlcyBubyBhcnF1aXZvIG9yaWdpbmFsIGRlIGRhZG9zIGJydXRvcyDDqQ0KbmVjZXNzw6FyaW8gaW5pY2lhciBhIHJvdGluYSBkZSBjYXJyZWdhbWVudG8gZGUgZGFkb3MgbmVjZXNzYXJpYW1lbnRlIGNvbQ0KYSBmdW7Dp8OjbyBgY2FycmVnYXJfZGFkb3NfYnJ1dG9zX3hsc3goKWAuDQoNCk91dHJvcyBjdWlkYWRvcy4uLg0KDQpJbWFnaW5hbmRvIHF1ZSBhIHBsYW5pbGhhIGRlIGRhZG9zIGRvIG1vbml0b3JhIMOpIGFsZ28gZGluw6JtaWNvLCBxdWUgbw0Kbm9tZSBkYXMgY29sdW5hcyBwb2RlIHNlciBlZGl0YWRvLi4uDQoNCiMjICoqQ29tbyBhYnJpciBvcyBhcnF1aXZvczogY29tbyBzYWx2YXIgZSBkZXNjb21wYWN0YXIgYSBwYXN0YS4gQWJyaXIgcHJvamV0byoqDQoNClVtIHBhc3NvIGEgcGFzc28gZGUgY29tbyBzYWx2YXIgYXJxdWl2byBjb20gb3MgY8OzZGlnb3MgZSBhYnJpci4uIFBvcg0KZXhlbXBsbywgZGEgZm9ybWEgY29tbyBlc3TDoSDDqSBpbnRlcmVzc2FudGUgZGVzY29tcGFjdGFyIGEgcGFzdGEgZQ0KYWNlc3NhciBvcyBhcnF1aXZvcyBhYnJpbmRvIG8gcHJvamV0by4gQWNobyBxdWUgaXNzbyBwb2RlIG11ZGFyLA0KZGVwZW5kZW5kbyBkZSBjb21vIHZpZXJtb3MgYSBlbnRyZWdhciBvIHByb2R1dG8gZmluYWwuIEVudMOjbyBwb2RlbW9zDQpwZW5zYXIgbmVzc2EgZXhwbGljYcOnw6NvIG5vIGZpbmFsLg0KDQojIyAqKkN1aWRhZG9zIGNvbSBkaXJldMOzcmlvKioNCg0KU2UgYSBnZW50ZSBhaW5kYSBwcmVjaXNhciB0ZXIgYWxndW0gdGlwbyBkZSBwcmVvY3VwYcOnw6NvIHF1YW50byBhIGlzc28uDQpBY2hvIHF1ZSBuw6NvLiBFeHBsaWNhciBhIGVzdHJ0dXJhIGRlIGRpcmV0w7NyaW9zIGRvIHByb2pldG8uDQoNCiMjICoqQ29tbyByb2RhciBjYWRhIHRpcG8gZGUgYXJxdWl2byAobWFya2Rvd24sIHNoaW55KSoqDQoNCk7Do28gw6kgdHJpdmlhbCBwYXJhIHF1ZW0gbsOjbyBlc3TDoSBhY29zdHVtYWRvLi4uIHVzYXIgcnVuQXBwLCBrbml0Li4uIGF0w6kNCm1lc21vIG8gc2hpZnQrZW50ZXIgcGFyYSByb2RhciBhcyBsaW5oYXMgZGUgY29tYW5kbyB1bWEgYSB1bWENCg0KIyAqKlBBUlRFIElJIC0tIENhcnJlZ2FuZG8gb3MgZGFkb3MgcGFyYSBvIFIqKg0KDQojIyAqKkRhZG9zIGJydXRvcyoqDQoNCk7Do28gcHJlY2lzYSBzZSBhc3N1c3RhciBjb20gYSBpbmZuaWRhZGUgZGUgY8OzZGlnb3Mgbm8gZXhlbXBsbyBhY2ltYS4NClNlcnZpdSBhcGVuYXMgcGFyYSBpbHVzdHJhciBxdWUgY29uc3RydWlyIGVzc2FzIGZ1bsOnw7VlcyBmYWNpbGl0YSBhDQpleGVjdcOnw6NvIGUgYSByZXByb2R1dGliaWxpZGFkZSBkYXMgYW7DoWxpc2UgZG9zIGRhZG9zIGRvIE1vbml0b3JhLiBQYXJhDQpjYWRhIHRhcmVmYSBleGlzdGUgdW1hIGZ1bsOnw6NvIGN1am8gZnVuY2lvbmFtZW50byBuw6NvIG5lY2Vzc2l0YSBkZQ0KcHJlZW5jaGltZW50byBkb3MgYXJndW1lbnRvcyAoZW1ib3JhIHNlamEgcG9zc8OtdmVsIGZvcm5lY2UtbG9zKS4gUG9yDQp0cmF6IGRhcyBjb3J0aW5hcywgYXMgZnVuw6fDtWVzIGV4ZWN1dGFtIGFzIHRhcmFmYXMgbmVjZXNzw6FyaWFzIHBhcmEgc2UNCm9idGVyIG8gcmVzdWx0YWRvIGRlc2VqYWRvLiBQb3IgZXhlbXBsbywgbyBtZXNtbyByZXN1bHRhZG8gcG9kZSBzZXINCm9idGlkbyB1dGlsaXphbmRvIGFwZW5hcyBkdWFzIGZ1bsOnw7VlczogYGNhcnJlZ2FyX2RhZG9zX2JydXRvc194bHN4KClgZQ0KYGdlcmFyX3RhYmRpbl9kYWRvc19icnV0b3MoKWAuDQoNCmBgYHtyfQ0KIyBjYXJyZWdhciBkYWRvcyBicnV0b3MNCmRhZG9zX2JydXRvcyA8LSBjYXJyZWdhcl9kYWRvc19icnV0b3NfeGxzeCgpDQoNCiMgZ2VyYXIgdGFiZWxhIGRpbmFtaWNhIGRvcyBkYWRvcyBicnV0b3MNCmdlcmFyX3RhYmRpbl9kYWRvc19icnV0b3MoKQ0KYGBgDQoNCkEgZnVuw6fDo28gYGdlcmFyX3RhYmRpbl9kYWRvc19icnV0b3MoKWAsIHBvciBjb25maWd1cmHDp8OjbywgZ2VyYSB1bWENCnRhYmVsYSBkaW7Dom1pY2EgY29tIDEwMDAgbGluaGFzLiBWb2PDqiBwb2RlIGNvbnRyb2xhciBvIG7Dum1lcm8gZGUgbGluaGFzDQpwZWxvIGFyZ3VtZW50byBgbl9saW5oYXMgPWAuIE1hcyBhdGVuw6fDo28hIEVsYSBuw6NvIGZ1bmNpb25hcsOhIGNvbSB1bQ0KbsO6bWVybyBzdXBlcmlvciBhICoqNC41MDAgbGluaGFzKiouIEFvIG11ZGFyIGEgZW50cmFkYSBkZSBkYWRvcyB1c2FuZG8gbw0KYXJndW1lbnRvIGBkYWRvcyA9YCwgY2VydGlmaXF1ZS1zZSBkZSBxdWUgc2V1IG7Dum1lcm8gZGUgbGluaGFzIG7Do28NCmV4Y2VkYSBlc3NlIGxpbWl0ZSAoZXguICoqNC41MDAqKikuIElOU0VSSVIgTk9UQSAoYXDDs3MgdGVzdGFyIGVtDQptw6FxdWluYXMgZGlmZXJlbnRlcykgRXNzZSB2YWxvciBwb2RlIHZhcmlhIGRlIGFjb3JkbyBjb20gYXMNCmNvbmZpZ3VyYcOnw7VlcyBkYSBzdWEgbcOhcXVpbmEuDQoNCmBgYHtyfQ0KZ2VyYXJfdGFiZGluX2RhZG9zX2JydXRvcygNCiAgbl9saW5oYXMgPSAxOjQ1MDANCikNCmBgYA0KDQojIyAqKkRhZG9zIGNvbXBsZXRvcyoqDQoNCi0gICB0b2RhcyBlc3DDqWNpZXMvVUNzIC0tIGNhcnJlZ2FfZGFkb3NfMS5SbWQgRGVzY3JldmVyIG8gcXVlIG9zIGRhZG9zDQogICAgdHJhemVtIGUgcG9ycXVlIGZvcmFtIGZvcm1hdGFkb3MgZGVzc2EgZm9ybWEuDQoNCmBgYHtyfQ0KIyBjYXJyZWdhciBkYWRvcyBwYXJhIG8gUg0KZGFkb3NfY29tcGxldG9zIDwtIGNhcnJlZ2FyX2RhZG9zX2NvbXBsZXRvcygpIA0KDQojIGdlcmFyIHRhYmVsYSBkaW5hbWljYSBkb3MgZGFkb3MgY29tcGxldG9zDQpnZXJhcl90YWJkaW5fZGFkb3NfY29tcGxldG9zKCkNCmBgYA0KDQojIyAqKkRhZG9zIGZpbHRyYWRvcyoqDQoNCi0gICBwb3IgZXNww6ljaWUvVUMgLS0gY2FycmVnYV9kYWRvc18yLlJtZCBhdMOpIG8gbW9tZW50byB1c2FkbyBjb20gbw0KICAgIGV4ZW1wbG8gZGEgY3V0aWEgbmEgUmVzZXggVGFwYWrDs3MtQXJhcGl1bnMgRGVzY3JldmVyIG8gcXVlIG9zIGRhZG9zDQogICAgdHJhemVtIGUgcG9ycXVlIGZvcmFtIGZvcm1hdGFkb3MgZGVzc2EgZm9ybWEuDQoNCmBgYHtyfQ0KIyBjYXJyZWdhciBkYWRvcyBwYXJhIG8gUg0KZGFkb3NfZmlsdHJhZG9zIDwtIGNhcnJlZ2FyX2RhZG9zX2ZpbHRyYWRvcygpDQoNCiMgZ2VyYXIgdGFiZWxhIGRpbsOibWljYSBkb3MgZGFkb3MgZml0cmFkb3MNCmdlcmFyX3RhYmRpbl9kYWRvc19maWx0cmFkb3MoKQ0KYGBgDQoNCiMgKipQYXJ0ZSBJSUkgLS0gVHJhbnNmb3JtYW5kbyBkYWRvcyBwYXJhIERpc3RhbmNlKioNCg0KIyMgKipEYWRvcyBjb21wbGV0b3MqKg0KDQotICAgdG9kYXMgZXNww6ljaWVzL1VDcyAtLSB0cmFuc2Zvcm1hcl9wYXJhX2Rpc3RhbmNlUi5SbWQNCg0KYGBge3J9DQojIHRyYW5zZm9ybWFyIG9zIGRhZG9zIHBhcmEgbyBmb3JtYXRvIGRvIERpc3RhbmNlDQpkYWRvc19kaXN0YW5jZVJfY29tcGxldG8gPC0gdHJhbnNmb3JtYXJfcGFyYV9kaXN0YW5jZVIoKQ0KDQojIGdlcmFyIHRhYmVsYSBkaW5hbWljYSBkb3MgZGFkb3Mgbm8gZm9ybWF0byBkbyBkaXN0YW5jZSBkbyBSDQpnZXJhcl90YWJkaW5fZGFkb3Nfc2VsZWNpb25hZG9zX2Rpc3RhbmNlUigpDQpgYGANCg0KRW0gcHJpbmPDrXBpbyB0dWRvIGNlcnRvIGF0w6kgYXF1aS4NCg0KYGBge3J9DQojIHRyYW5zZm9ybWFyIG9zIGRhZG9zIHBhcmEgbyBmb3JtYXRvIGRvIERpc3RhbmNlDQpkYWRvc19kaXN0YW5jZV9yX2NvdmFyaWF2ZWlzIDwtIHRyYW5zZm9ybWFyX3BhcmFfZGlzdGFuY2VSX2NvdmFyaWF2ZWlzKCkNCg0KIyB0YWJkaW4gZGUgZGFkb3NfZGlzdGFuY2VSX2NvdmFyaWF2ZWlzDQpnZXJhcl90YWJkaW5fZGFkb3Nfc2VsZWNpb25hZG9zX2Rpc3RhbmNlUl9jb3YoKQ0KYGBgDQoNCiMgKipQQVJURSBJViAtLSBFeHBsb3JhbmRvIGUgc2VsZWNpb25hbmRvIG9zIGRhZG9zIHBhcmEgYXMgYW7DoWxpc2VzKioNCg0KIyMgKipTZWxlY2lvbmFuZG8gb3MgbWVsaG9yZXMgbW9kZWxvcyBkZSBlc3R1ZG8gZGUgYWNvcmRvIGNvbSBvcyBkYWRvcyoqDQoNCkFsZ3VucyBjdWlkYWRvcyBkZXZlbSBzZXIgdG9tYWRvcyBuYSBwcmVwYXJhw6fDo28gZG9zIGRhZG9zIGFudGVzIGRlIHNlcmVtDQphbmFsaXNhZG9zLiBPIHByaW1laXJvIGRlbGVzIMOpIG8gY3VpZGFkbyB0YXhvbsO0bWljby4gUGFyYSBvcyBkYWRvcyBkbw0KTW9uaXRvcmEgcmVjb21lbmRhLXNlIG8gdXNvIGRvcyBkYWRvcyBkYXMgZXNww6ljaWVzIHZhbGlkYWRhcyBwYXJhDQphbsOhbGlzZSBwZWxvIElDTUJpbywgY29uZm9ybWUgbyBtb2RlbG8gdXRpbGl6YWRvIHBhcmEgZXN0ZSBmbHV4byBkZQ0KdHJhYmFsaG8uDQoNCkFsZ3VucyBwcm9ibGVtYXMgY29tIG9zIGRhZG9zLCBxdWUgcG9kZW0gdHJhemVyIGVmZWl0b3MgaW5kZXNlamFkb3MNCnNvYnJlIGFzIGFuw6FsaXNlcywgcG9kZW0gc2VyIGRldGVjdGFkb3MgZHVyYW50ZSBhIGZhc2UgZGUgZXhwbG9yYcOnw6NvLiBBbw0Kc2VsZWNpb25hciBvcyBkYWRvcyBxdWUgc2Vyw6NvIGFuYWxpc2Fkb3MsIMOpIGltcG9ydGFudGUgb2JzZXJ2YXIgb3MNCnNlZ3VpbnRlcyBhc3BlY3RvczoNCg0KKipTdWZpY8OqbmNpYSBBbW9zdHJhbCAtIG7Dum1lcm8gZGUgb2NvcnLDqm5jaWFzIHBvciBlc3DDqWNpZToqKg0KDQpQYXJhIHF1ZSBvIG3DqXRvZG8gZGUgYW7DoWxpc2UgcG9yIGRpc3TDom5jaWEgcG9zc2Egc2VyIHV0aWxpemFkbyBwYXJhDQplc3RpbWF0aXZhcyBiYXNlYWRhcyBlbSBtb2RlbG9zLCBzw6NvIHJlY29tZW5kYWRhcyBxdWFudGlkYWRlcyBtw61uaW1hcyBkZQ0KcmVnaXN0cm9zIGRlIG9jb3Jyw6puY2lhIGUgZGUgdHJhbnNlY3RvcyAoVW5pZGFkZXMgQW1vc3RyYWlzKS4gU2VndW5kbw0KQlVDS0xBTkQgZXQuIGFsLiAoMjAxNSksIG8gbsO6bWVybyBtw61uaW1vIHN1Z2VyaWRvIGRlIGFuaW1haXMgb3UgZ3J1cG9zDQoob2NvcnLDqm5jaWFzKSDDqSBkZSA2MCAtLSA4MCBhbmltYWlzIChvdSBncnVwb3MpIHF1YW5kbyBhIGFtb3N0cmFnZW0gw6kNCmZlaXRhIHBlbG8gbcOpdG9kbyBkb3MgdHJhbnNlY3RvcyBsaW5lYXJlcy4gw4kgcG9zc8OtdmVsIHV0aWxpemFyIG7Dum1lcm9zDQptZW5vcmVzIHF1ZSBlc3RlcyBwYXJhIHJlYWxpemFyIGFzIGFuw6FsaXNlcywgcG9yw6ltIGRldmUtc2UgdGVyIG8gY3VpZGFkbw0KZGUgdmVyaWZpY2FyIHNlIGFzIGZ1bsOnw7VlcyBkZSBkZXRlY8Onw6NvIGVzdMOjbyBiZW0gbW9kZWxhZGFzLg0KDQpQYXJhIGRhZG9zIHF1ZSBzZXLDo28gZXN0cmF0aWZpY2Fkb3MgKGRpdmlkaWRvcyBlbSBzdWJjb25qdW50b3MpLCBlc3Rlcw0KbsO6bWVyb3MgcmVjb21lbmRhZG9zIHNlIGFwbGljYW0gYSBjYWRhIHN1YmNvbmp1bnRvLiBJc3NvIG9jb3JyZSBwb3JxdWUNCmFzIGZ1bsOnw7VlcyBkZSBkZXRlY8Onw6NvIHNlcsOjbyBtb2RlbGFkYXMgcGFyYSBjYWRhIGVzdHJhdG8NCihwLmV4LmBSZWdpb24uTGFiZWxgKSwgYWzDqW0gZGEgZnVuw6fDo28gZGUgZGV0ZWPDp8OjbyBwYXJhIG9zIGRhZG9zIGdsb2JhaXMuDQpVbSBleGVtcGxvIHNlcmlhIGEgYW7DoWxpc2UgZG9zIGRhZG9zLCBwYXJhIHVtYSBtZXNtYSBlc3DDqWNpZSwgZW0NCmRpZmVyZW50ZXMgVUNzLiBOZXN0ZSBjYXNvLCBvIGlkZWFsIHNlcmlhIHRlciBhIHN1ZmljacOqbmNpYSBhbW9zdHJhbA0KbcOtbmltYSBlbSBjYWRhIFVDIHBhcmEgdXNhciBlc3RyYXRpZmljYcOnw6NvIGUgZXN0aW1hciBhYnVuZMOibmNpYXMgZQ0KZGVuc2lkYWRlcyBlbSBjYWRhIHVtYSBkYXMgVUNzLg0KDQoqKlN1ZmljacOqbmNpYSBhbW9zdHJhbCAtIHLDqXBsaWNhcyBlIHJlcGV0acOnw7VlcyoqDQoNClBhcmEgcXVlIGhhamEgdW1hIGJvYSBjb2JlcnR1cmEgZGEgw6FyZWEgZGUgZXN0dWRvIGUgdGFtYsOpbSB1bWEgYm9hDQpxdWFudGlkYWRlIGRlIGFtb3N0cmFzIGluZGVwZW5kZW50ZXMgcGFyYSBlc3RpbWFyIGFzIGFidW5kw6JuY2lhcyBlDQpkZW5zaWRhZGVzIGRhcyBlc3DDqWNpZXMsIMOpIGRlc2Vqw6F2ZWwgdW0gbsO6bWVybyBzYXRpc2ZhdMOzcmlvIGRlIHLDqXBsaWNhcy4NClNlZ3VuZG8gQlVDS0xBTkQgZXQgYWwuICgyMDE1KSwgbyBuw7ptZXJvIG3DrW5pbW8gZGUgcsOpcGxpY2FzIHBhcmEgb3MNCnRyYW5zZWN0b3MgZGV2ZSBzZXIgZGUgMTAtMjAsIG8gcXVlIGRldmUgYXVtZW50YXIgcGFyYSBlc3DDqWNpZXMgY3VqYXMNCnBvcHVsYcOnw7VlcyBzw6NvIGRpc3RyaWJ1w61kYXMgZW0gbWFuY2hhcy4NCg0KRGUgZm9ybWEgZ2VyYWwsIHBhcmEgY2FkYSBVQywgbyBuw7ptZXJvIGRlIHLDqXBsaWNhcyBkbyBQcm9ncmFtYSBNb25pdG9yYQ0KZXN0w6EgYWJhaXhvIGRvIHJlY29tZW5kYWRvLiBPIGRlbGluYW1lbnRvIGFtb3N0cmFsIGF0dWFsIHBhcmEgYQ0KY29tcG9udGVudGUgRmxvcmVzdGFsIGRvIHN1YnByb2dyYW1hIFRlcnJlc3RyZSBlc3RhYmVsZWNlIHVtIG7Dum1lcm8NCm3DrW5pbW8gZGUgdHLDqnMgRXN0YcOnw7VlcyBBbW9zdHJhaXMgcG9yIFVuaWRhZGUgZGUgQ29uc2VydmHDp8OjbywgbyBxdWUgw6kgbw0KY2FzbyBkZSBtdWl0YXMgVUNzLCBjaGVnYW5kbyBhbyBtw6F4aW1vIGRlIFhYIGVzdGHDp8O1ZXMgYW1vc3RyYWlzIHBvciBVQy4NCk8gYmFpeG8gbsO6bWVybyBkZSByw6lwbGljYXMgbsOjbyBjaGVnYSBhIHNlciB1bSBwcm9ibGVtYSBuYSBlc3RpbWF0aXZhIGRlDQpkZW5zaWRhZGUgZGEgw4FyZWEgQ29iZXJ0YSBwZWxhIGFtb3N0cmFnZW0gKCpDb3ZlcmVkIEFyZWEqKSwgbWFzIGxpbWl0YQ0KdW1hIGJvYSBlc3RpbWF0aXZhIGRlIGRlbnNpZGFkZSB0b3RhbCBwYXJhIGEgVW5pZGFkZSBkZSBDb25zZXJ2YcOnw6NvDQooKlN0dWR5IEFyZWEqKS4NCg0KVW0gb3V0cm8gYXNwZWN0byByZWxhY2lvbmFkbyBhIGFtb3N0cmFnZW0gw6kgbyBuw7ptZXJvIGRlIHJlcGV0acOnw7VlcyBwb3INCnRyYW5zZWN0by4gU2VndW5kbyBCVUtMQU5EIGV0IGFsICgyMDAxLCBwZyA3OSksIGFzIHJlcGV0acOnw7VlcyBkZXZlbSBzZXINCmluY29ycG9yYWRhcyBubyBlc2ZvcsOnbyBhbW9zdHJhbCBtdWx0aXBsaWNhbmRvLXNlIG8gbsO6bWVybyBkZSB2ZXplcyBxdWUNCm8gdHJhbnNlY3RvIGZvaSBwZXJjb3JyaWRvIHBlbG8gY29tcHJpbWVudG8gZG8gdHJhbnNlY3RvLiBBIG1lc21hDQpyZWNvbWVuZGHDp8OjbyDDqSBkYWRhIHBlbG8gQ3Vyc28gT25saW5lIGVtIERpc3RhbmNlIFNhbXBsaW5nDQpbbGlua10oaHR0cHM6Ly93b3Jrc2hvcHMuZGlzdGFuY2VzYW1wbGluZy5vcmcvb25saW5lLWNvdXJzZS9sZWN0dXJlcGRmcy9DaDQvTDQtMyUyMFNhbXBsZSUyMFNpemUucGRmKS4NCkVzc2UgYWp1c3RlIG5vIGVzZm9yw6dvIGFtb3N0cmFsIG7Do28gZGV2ZSB0ZXIgZ3JhbmRlcyBjb25zZXF1w6puY2lhcyBwYXJhDQp1bSBiYWl4byBuw7ptZXJvIGRlIHJlcGV0acOnw7Vlcy4gUG9yw6ltLCBwYXJhIG7Dum1lcm9zIGFsdG9zLCBsZXZhIGEgdW1hDQppbmZsYWdlbSBubyB0YW1hbmhvIGRhIMOhcmVhIGNvYmVydGEuIEFwZW5hcyBwYXJhIGlsdXN0YXIgY29tIHVtIGV4ZW1wbG8sDQpwYXJhIG9zIGRhZG9zIGRhIFJlc2V4IFRhcGFqw7NzLUFyYXBpbnVucywgYSBFc3Rhw6fDo28gQW1vc3RyYWwgQm9pbSBmb2kNCnBlcmNvcnJpZGEgZHVyYW50ZSA3MCBkaWFzIGRlIGFtb3N0cmFnZW0uIElzc28gc2lnbmlmaWNhIHF1ZSBhanVzdGFuZG8gbw0KY29tcHJpbWVudG8gZG8gdHJhbnNlY3RvIGRlIDUga20gcGVsbyBuw7ptZXJvIGRlIHJlcGV0acOnw7VlcywgbyBlc2ZvcsOnbw0KYW1vc3RyYWwgcGFzc291IHBhcmEgMzUwIGttLiBBIMOhcmVhIGNvYmVydGEgYXVtZW50b3UgZW0gNzB4LCBvIHF1ZSB0ZXLDoQ0KY29uc2VxdcOqbmNpYXMgc29icmUgYSBlc3RpbWF0aXZhIGRlbnNpZGFkZSwgcXVlIHRlbmRlcsOhIGEgc2VyDQpzdWJlc3RpbWFkYS4gQWzDqW0gZGlzc28sIG8gY29lZmljaWVudGUgZGUgdmFyaWHDp8OjbyBkYXMgZXN0aW1hdGl2YXMgZGUNCmFidW5kw6JuY2lhIGUgZGVuc2lkYWRlIHRhbWLDqW0gdGVuZGVyw6EgYSBhdW1lbnRhciBwZWxvIGVmZWl0byBkYXMNCnZhcmlhw6fDtWVzIHRlbXBvcmFpcyBlbnRyZSBhcyBhbW9zdHJhZ2Vucy4NCg0KVW1hIGZvcm1hIGRlIGxpZGFyIGNvbSBvIGV4Y2Vzc28gZGUgYW1vc3RyYWdlbnMgcmVwZXRpZGFzIMOpIHRyYXRhciBhcw0KcmVwZXRpw6fDtWVzIGNvbW8gZWZlaXRvcyBhbGVhdMOzcmlvcyBkb3MgbW9kZWxvcy4gSXNzbyByZXF1ZXIgbyB1c28gZGUNCmFib3JkYWdlbnMgcXVlIHbDo28gYWzDqW0gZGEgYW1vc3RyYWdlbSBwb3IgZGlzdMOibmNpYSBjb252ZWNpb25hbCwgY29tbyBvDQp1c28gZGUgTWl4ZWQgRWZmZWN0IE1vZGVscyBlIE1vZGVsb3MgSGllcsOhcnF1aWNvcyAocC4gZXguIE9FREVLT1ZFTiBldC4NCmFsLiAyMDEzLCAyMDE0KSBFc3NhcyBhYm9yZGFnZW5zIGFpbmRhIG7Do28gZm9yYW0gaW1wbGVtZW50YWRhcyBlbSBub3Nzbw0KZmx1eG8gZGUgdHJhYmFsaG8gYXTDqSBhIHByZXNlbnRlIHZlcnPDo28gZSBwcmV0ZW5kZW1vcyB0ZXN0w6EtbGEgYXTDqSBhDQpvZmljaW5hIGRlIGNhcGFjaXRhw6fDo28uDQoNCioqRGlzdHJpYnVpw6fDo28gZGUgZnJlcXXDqm5jaWEgZGFzIG9jb3Jyw6puY2lhcyBlbSByZWxhw6fDo28gw6AgZGlzdMOibmNpYSAtDQplZmVpdG9zIGluZGVzZWphZG9zKioNCg0KQSBkaXN0cmlidWnDp8OjbyBpZGVhbCBkYXMgZnJlcXXDqm5jaWFzIGRlIG9jb3Jyw6puY2lhIGVtIHJlbGHDp8OjbyDDoA0KZGlzdMOibmNpYSBkZXZlIGFwcmVzZW50YXIgYXMgc2VndWludGVzIGNhcmFjdGVyw61zdGljYXM6IGEgZnJlcXXDqm5jaWEgZGUNCm9jb3Jyw6puY2lhIGRldmUgc2VyIG1haW9yIHByw7N4aW1vIGEgemVybywgYXByZXNlbnRhciB1bSBsb25nbyBwbGF0w7QNCihvbWJybyksIGUgZGVjYWlyIGdyYWRhdGl2YW1lbnRlIGNvbSBvIGF1bWVudG8gZGEgZGlzdMOibmNpYS4gSXNzbw0Kc2lnbmlmaWNhIHF1ZSBvcyBhbmltYWlzIHPDo28gdG90YWxtZW50ZSBkZXRlY3TDoXZlaXMgbmEgZGlzdMOibmNpYSB6ZXJvLA0Kc2VndWVtIHNlbmRvIGJlbSBkZXRlY3TDoXZlaXMgYSBkaXN0w6JuY2lhcyBjdXJ0YXMgZSB2w6NvIHBlcmRlbmRvDQpkZXRlY3RhYmlsaWRhZGUgZ3JhZGF0aXZhbWVudGUgY29tIG8gYXVtZW50byBkYSBkaXN0w6JuY2lhLg0KDQpQb3IgaXNzbywgdW1hIGRhcyBldGFwYXMgZXhwbG9yYXTDs3JpYXMgw6kgYXZhbGlhciBvIGhpc3RvZ3JhbWEgZGUNCmZyZXF1w6puY2lhcyBkZSBvY29ycsOqbmNpYSBhbyBsb25nbyBkYSBkaXN0w6JuY2lhIGVtIHJlbGHDp8OjbyBhbyB0cmFuc2VjdG8NCihvcMOnw6NvIGFiYWl4bykuIEFsZ3VtYXMgZGlzdHJpYnVpw6fDtWVzIGluZGljYW0gcHJvYmxlbWFzIG5vcyBkYWRvcyBxdWUNCnBvZGVtIGRpZmljdWx0YXIgbyBhanVzdGUgZGFzIGZ1bsOnw7VlcyBkZSBkZXRlY8Onw6NvLiBUYWlzIGNvbW86DQoNCipQaWNvIGRlIG9jb3Jyw6puY2lhcyBwcsOzeGltb3Mgw6AgZGlzdMOibmNpYSB6ZXJvIC0gc3Bpa2UgbmVhciB6ZXJvDQpkaXN0YW5jZSoNCg0KSXNzbyBvY29ycmUgcXVhbmRvIG8gbsO6bWVybyBkZSBvYnNlcnZhw6fDtWVzIHByw7N4aW1vcyDDoCBkaXN0w6JuY2lhIHplcm8gw6kNCmluZmxhZG8gZW0gcmVsYcOnw6NvIMOgcyBkZW1haXMgZGlzdMOibmNpYXMuIE8gZWZlaXRvIGdyw6FmaWNvIHNlcsOhIHVtIHBpY28NCm5vIGhpc3RvZ3JhbWEgZW0gemVybyBvdSBwcsOzeGltbyBhIHplcm8sIGNvbmZvcm1lIG8gZXhlbXBsbyBhYmFpeG8gcGFyYQ0Kb3MgZGFkb3MgZXh0cmHDrWRvcyBkYXMgY3V0aWFzICgqRGFzeXByb2N0YSBjcm9jb25vdGEqKSBuYSBSZXNleA0KVGFwYWrDs3MtQXJhcGl1bnMuDQoNCiFbRGlzdHJpYnVpY2FvIGRlIEZyZXF1ZW5jaWEgcGFyYSAqRGFzeXByb2N0YSBjcm9jb25vdGEqIG5hIFJlc2V4DQpUYXBham9zLUFyYXBpdW5zXShDOiU1Q1VzZXJzJTVDbHVmdXMlNUNPbmVEcml2ZSU1Q0NvbnN1bHRvcmlhcyU1Q1dXRl9Fc3BlY2llcyU1Q1Byb2R1dG8yX0NvZGlnb3MlNUNEaXN0cmlidWljYW9fZnJlcV9EYXN5cHJvY3RhX1Jlc2V4VGFwYWpvcy5wbmcpe3dpZHRoPSI3NSUifQ0KDQpFc3RlIHRpcG8gZGUgZGlzdHJpYnVpw6fDo28gZm9pIHVtIHBhZHLDo28gcGFyYSBhcyBlc3DDqWNpZXMgY29tIG8gbWFpb3INCm7Dum1lcm8gZGUgb2NvcnLDqm5jaWEgbm9zIGRhZG9zIGRlIGF2ZXMgZSBtYW3DrWZlcm9zIGRvIFByb2dyYW1hIE1vbml0b3JhDQpGbG9yZXN0YWwuIEFjcmVkaXRhbW9zIHF1ZSBleGlzdGVtIGRvaXMgZmF0b3JlcyBxdWUgcG9kZW0gZXN0YXIgY2F1c2FuZG8NCmVzc2UgYWPDum11bG8gZGUgZGFkb3MgZW0gemVybyBvdSBwcsOzeGltbyBhIGVsZS4gVW0gZGVsZXMgc2VyaWEgdW0gdmnDqXMNCnBhcmEgYXZpc3RhbWVudG8gZGUgYW5pbWFpcyBuYSB0cmlsaGEgZW0gYW1iaWVudGVzIGRlIGZsb3Jlc3RhLiBBcw0KdHJpbGhhcyBwb2RlbSBhdHJhaXIgYW5pbWFpcywgZSB0YW1iw6ltIG9mZXJlY2VtIG1lbGhvciB2aXNpYmlsaWRhZGUgZW0NCnJlbGHDp8OjbyDDoCBmbG9yZXN0YSwgZXNwZWNpYWxtZW50ZSBzZSBvIHN1Yi1ib3NxdWUgZm9yIGRlbnNvIC4gTyBvdXRybw0KZmF0b3Igc2VyaWEgdW0gcG9zc8OtdmVsIGFycmVkb25kYW1lbnRvIG5hcyBkaXN0w6JuY2lhcyBwcsOzeGltYXMgYSB6ZXJvLA0KcG9kZSBnZXJhciB1bSAiYW1vbnRvYW1lbnRvIiBub3MgZGFkb3MgKCpoZWFwaW5nKikuIFJlY29tZW5kYS1zZSBxdWUNCnZhbG9yZXMgZGUgZGlzdMOibmNpYSBwZXJwZW5kaWN1bGFyIG51bmNhIHNlamFtIGFycmVkb25kYWRvcy4NCg0KKlJlc3Bvc3RhIGV2YXNpdmEgZGFzIGVzcMOpY2llcyBlbSByZWxhw6fDo28gYW8gb2JzZXJ2YWRvcioNCg0KUGFyYSBlc3DDqWNpZXMgcXVlIHBvZGVtIGFwcmVzZW50YXIgcmVzcG9zdGEgZGUgZGVzbG9jYW1lbnRvIGVtIHJlbGHDp8Ojbw0KYW8gb2JzZXJ2YWRvciwgdW0gZG9zIGVmZWl0b3MgaW5kZXNlamFkb3Mgbm9zIGRhZG9zIMOpIG8gZGVzbG9jYW1lbnRvIGRhcw0KbWFpb3JlcyBmcmVxdcOqbmNpYXMgZGUgb2JzZXJ2YcOnw7VlcyBwYXJhIGFzIGRpc3TDom5jaWFzIHBlcnBlbmRpY3VsYXJlcw0KaW50ZXJtZWRpw6FyaWFzLg0KDQoqKnBhcmVpIHBvciBhcXVpLi4uIGNvbnRpbnVhLi4uIHZlciBtZWxob3IgYSBlc3RyYXTDqWdpYSBkZSBhZ3J1cGFyIG9zDQpkYWRvcyoqDQoNCmVzcMOpY2llcyBjb20gbWFpb3Igdm9sdW1lIGRlIGRhZG9zIHRvdGFsDQoNCi0gICBtYWlvciB2b2x1bWUgZGUgZGFkb3MgcG9yIFVDIC0tIGV4cGxvcmHDp8Ojb18wMS5uYi5odG1sIChhY2hvIHF1ZSBvDQogICAgLlJtZCBwYXJhIGdlcmFyIGVzc2UgaHRtbCBuw6NvIGVzdMOhIG5hIHBhc3RhIE1vbml0b3JhKS4gRXUgdGluaGENCiAgICBnb3N0YWRvIGJhc3RhbnRlIGRlc3NlIGRvY3VtZW50bywgY29tIGFzIHRhYmVsYXMgZGluw6JtaWNhcy4gVGFsdmV6DQogICAgZMOqIHBhcmEgc2VsZWNpb25hciBhcyBwZXJndW50YXMgcXVlIHPDo28gdsOhbGlkYXMgZGUgZGVpeGFyLyB0aXJhci8NCiAgICBpbmNsdWlyLiBXV0YgLSBQcm9qZXRvIE1vbml0b3JhDQotICAgZXNww6ljaWVzIHZhbGlkYWRhcw0KLSAgIC4uLg0KDQojIyMgKipFeHBsb3Jhw6fDo28gZSBzZWxlw6fDo28gZGUgZGFkb3MqKg0KDQojIyMjICoqQXNwZWN0b3MgcmVsYWNpb25hZG9zIGFvIG7Dum1lcm8gdG90YWwgZGUgb2JzZXJ2YcOnw7VlcyoqDQoNClNpc3RlbWF0aXphciBvcyBjcml0w6lyaW9zIHV0aWxpemFkb3MgcGFyYSBlbGltaW5hciBvYnNlcnZhw6fDtWVzIChsaW5oYXMpLg0KDQpQZW5zYXIgbnVtIGVzcXVlbWEgZGUgw6Fydm9yZSBkZSBkZWNpc8OjbyBwYXJhIHNlIGNoZWdhciBhbyBzdWJjb25qdW50byBkZQ0KZGFkb3MgcXVlIHNlcsOhIGFuYWxpc2Fkb3MuDQoNCiMjIyMgKipRdWFudGFzIG9ic2VydmHDp8O1ZXMgZm9yYW0gdmFsaWRhZGFzIHBhcmEgcXVhaXMgbsOtdmVpcyB0YXhvbsO0bWljb3M/KioNCg0KRXNzYXMgb3BlcmHDp8O1ZXMgc8OjbyByZWFsaXphZGFzIHNvYnJlIGEgdGFiZWxhIGRlIGRhZG9zIGBkYWRvc19jb21wbGV0b3NgDQpwb2lzIG9zIGRhZG9zIHF1ZSBmb3JhbSB0cmFuc2Zvcm1hZG9zIHBhcmEgbyBmb3JtYXRvIGRvIGRpc3RhY2Ugbm8gUiBuw6NvDQpwb3NzdWVtIGEgY29sdW5hIGB2YWxpZGF0aW9uYCwgbmVjZXNzw6FyaWEgcGFyYSBlc3NhcyBvcGVyZWHDp8O1ZXMuIE1haXMgYQ0KZnJlbnRlIG8gcHJvY2VkaW1lbnRvIGRlIGNvbW8gb2J0ZXIgb3MgZGFkb3Mgc2VsZWNpb25hZG9zIGUNCnRyYW5zZm9ybWF0b3MgcGFyYSBvIGZvcm1hdG8gZGFzIGFuw6FsaXNlcyBzZXLDoSBkZW1vbnN0cmFkby4NCg0KYGBge3J9DQojIGNvbnRhciBvYnNlcnZhw6fDtWVzIHZhbGlkYWRhcyBhbyBuw612ZWwgZGUgZXNww6ljaWUNCm5fb2JzX3ZhbGlkYWRhcyA8LSBjb250YXJfbl9vYnNfdmFsaWRhZGFzKCkNCm5fb2JzX3ZhbGlkYWRhcw0KYGBgDQoNCkZvcmFtIHNlbGVjaW9uYWRhcyBhcGVuYXMgYXMgb2JzZXJ2YcOnw7VlcyB2YWxpZGFkYXMgYW8gbsOtdmVsIGRlIGVzcMOpY2llLA0Kc29tYW5kbyB1bSB0b3RhbCBgciBuX29ic192YWxpZGFkYXNbMV1gIG9ic2VydmHDp8O1ZXMuDQoNCmBgYHtyfQ0KIyBnZXJhciBncsOhZmljbyBjb20gbsO6bWVybyBvYnNlcnZhw6fDtWVzIHZhbGlkYWRhcyBwYXJhIGNhZGEgbsOtdmVsIHRheG9uw7RtaWNvDQpwbG90YXJfbl9vYnNfdmFsaWRhZGFzX2ludGVyYXRpdm8oKQ0KYGBgDQoNCkZpbG5hbG1lbnRlIGNoZWdhbW9zIGFvIHN1YmNvbmp1bnRvIGRvcyBkYWRvcyBxdWUgc2Vyw6EgdXRpbGl6YWRvIHBhcmENCnNlbGVjaW9uYXIgcXVhaXMgZXNww6ljaWVzIHNlcsOjbyBhbmFsaXNhZGFzLg0KDQpgYGB7cn0NCiMgZ2VyYXIgdGFiZWxhIGRlIGRhZG9zIHNlbGVjaW9uYWRvcw0KZGFkb3Nfc2VsZWNpb25hZG9zIDwtIGNhcnJlZ2FyX2RhZG9zX3NlbGVjaW9uYWRvcygpDQoNCiMgZ2VyYXIgdGFiZGluIGRhZG9zX3NlbGVjaW9uYWRvcyANCmdlcmFyX3RhYmRpbl9kYWRvc19zZWxlY2lvbmFkb3MoKQ0KYGBgDQoNCiMjIyMgKipRdWFudGFzIHVuaWRhZGVzIGRlIGNvbnNlcnZhw6fDo28gYW8gdG9kbz8qKg0KDQpgYGB7ciBuX2RlX3Vjc30NCiMgY29udGFyIG7Dum1lcm8gdG90YWwgZGUgVUMncyANCm5fdWNzIDwtIGNvbnRhcl9uX3VjKCkNCm5fdWNzDQpgYGANCg0KT3MgZGFkb3Mgc8OjbyBwcm92ZW5pZW50ZXMgZGUgYHIgbl91Y3NgIHVuaWRhZGVzIGRlIGNvbnNlcnZhw6fDo28gYW8gdG9kby4NCg0KIyMjIyAqKlF1YW50YXMgZXNww6ljaWVzIGFvIHRvZG8/KioNCg0KYGBge3J9DQpuX3NwIDwtIGNvbnRhcl9uX3NwKCkNCm5fc3ANCmBgYA0KDQpBdMOpIGFxdWkgdGVtb3MgZGFkb3MgcGFyYSBgciBuX3NwYCBlc3DDqWNpZXMuDQoNCiMjIyMgKipRdWFudGFzIG9ic2VydmHDp8O1ZXMgcG9yIHVuaWRhZGUgZGUgY29uc2VydmHDp8OjbyBhbyB0b2RvPyoqDQoNCkFzIFVDJ3MgZm9yYW0gZmlsdHJhZGFzIGRlIGFjb3JkbyBjb20gbyBuw7ptZXJvIGRlIG9ic2VydmHDp8O1ZXMgcGVybWl0aXIgYQ0KdmlzdWFsaXphw6fDo28uDQoNCkEgZnVuw6fDo28gZGUgY29udGFnZW0gZGUgVUMncyBnZXJvdSA0MCBVQydzLCBtYXMgc8OzIGjDoSBvYnNlcnZhw6fDtWVzIHBhcmENCjM4LiAqTGVtYnJhciBkZSB2ZXJpZmljYXIgaXNzbyouDQoNCmBgYHtyfQ0KIyBjb250YXIgbsO6bWVybyBkZSBvYnNlcnZhw6fDtWVzIHBvciBVQw0Kbl9vYnNfdWMgPC0gY29udGFyX25fb2JzX3VjKCkNCg0KIyBnZXJhciB0YWJkaW4NCmdlcmFyX3RhYmRpbl9uX29ic191YygpDQpgYGANCg0KKkFkaWNpb25hciBvIG5vbWUgY29tcGxldG8gZGEgVUMgbmEgY2FpeGEgaW50ZXJhdGl2YSBkbyBncsOhZmljbyouDQoqSWRlbnRpZmljYXIgb3MgcGxvdGVzIGNvbSBzdWJ0w610dWxvcyBleCB0ZW50YXIgYWRpY2lvbmFyIHTDrXR1bG8gYW9zDQpwbG90ZXMqICoqQWRpY2lvbmFyIG5vbWVzIGRhcyBVQ3Mgbm9zIDMgcHJpbWVpcm9zIGfDoWZpY29zDQooZGVzY29tcGFydGlsaGFyIGVpeG8geCkqKg0KDQpgYGB7ciwgZmlnLmhlaWdodD0yMCwgZmlnLmFsaWduPSdjZW50ZXInfQ0KIyBwbG90YXIgbyBuw7ptZXJvIGRlIG9ic2VydmHDp8O1ZXMgcG9yIFVDDQpwbG90YXJfbl9vYnNfdWNfaW50ZXJhdGl2bygpDQpgYGANCg0KIyMjIyAqKlF1YW50YXMgb2JzZXJ2YcOnw7VlcyBwYXJhIGNhZGEgZXNww6ljaWU/KioNCg0KTsO6bWVybyBkZSBvYnNlcnZhw6fDtWVzIHBvciBlc3DDqWNpZS4NCg0KYGBge3IsIGZpZy5oZWlnaHQ9MjB9DQojIGNvbnRhciB0b3RhbCBzcA0Kbl9zcCA8LSBjb250YXJfbl9zcCgpDQpuX3NwDQpgYGANCg0KYGBge3J9DQojIGNvbnRhciBvIG7Dum1lcm8gZGUgb2JzZXJ2YcOnw7VlcyBwb3IgZXNww6ljaWUNCm5fb2JzX3NwIDwtIGNvbnRhcl9uX29ic19zcCgpDQoNCiMgZ2VyYXIgdGFiZWxhIGRpbsOibWljYSBjb20gbyBuw7ptZXJvIHRvdGFsIGRlIG9ic2V2YcOnw7VlcyBwb3IgZXNww6ljaWUNCmdlcmFyX3RhYmRpbl9uX29ic19zcCgpDQpgYGANCg0KRXNzZSBncsOhZmljbyBwb2RlIG1lbGhvcmFyLiBDb21wYXJ0aWxoYXIgbyBlaXhvIHg/IEFkaWNpb25hciB0w610dWxvIGFvDQplaXhvIHguLi4NCg0KYGBge3IsIGZpZy5oZWlnaHQ9MjB9DQojIHBsb3RhciBvIG8gbsO6bWVybyBkZSBvYnNlcnZhw6fDtWVzIHBvciBVQw0KcGxvdGFyX25fb2JzX3NwX2ludGVyYXRpdm8oKQ0KYGBgDQoNClRhYmVsYSBpbnRlcmF0aXZhIHBhcmEgY29uc3VsdGEgZG8gbsO6bWVybyBkZSBvYnNlcnZhw6fDtWVzIHBvciBlc3DDqWNpZS4NCg0KYGBge3J9DQpnZXJhcl90YWJkaW5fbl9vYnNfc3AoKQ0KYGBgDQoNCiMjIyMgKipRdWFpcyBlIHF1YW50YXMgb2JzZXJ2YcOnw7VlcyBwYXJhIGNhZGEgZXNww6ljaWUgcG9yIHVuaWRhZGVzIGRlIGNvbnNlcnZhw6fDo28/KioNCg0KYGBge3J9DQojIGdlcmFyIHRhYmVsYSBjb20gbyBuw7ptZXJvIGRlIG9ic2VydmHDp8O1ZXMgcG9yIGVzcMOpY2llIGUgcG9yIFVDDQpuX29ic19zcF91YyA8LSBjb250YXJfbl9vYnNfc3BfdWMoKQ0Kbl9vYnNfc3BfdWMNCmBgYA0KDQoqKlJlcGVuc2FyIGVzc2UgZ3LDoWZpY28uLi4qKiBUYWx2ZXogbsOjbyBzZWphIG5lY2Vzc8OhcmlvLi4uDQoNCmBgYHtyLCBmaWcuaGVpZ2h0PTIwfQ0KcGxvdGFyX25fb2JzX3NwX3VjX2ludGVyYXRpdm8oKQ0KYGBgDQoNCkdlcmFyIGZ1bsOnw6NvIHRhYmVsYSBkaW7Dom1pY2EuDQoNCmBgYHtyfQ0KZ2VyYXJfdGFiZGluX25fb2JzX3NwX3VjKCkNCmBgYA0KDQojIyMjICoqUXVhbnRhcyB1bmlkYWRlcyBkZSBjb25zZXJ2YcOnw6NvIGZvcmFtIGFtb3N0cmFkYXMgZW0gY2FkYSBhbm8/KioNCg0KR2VyYXIgZnVuw6fDo28gcGFyYSB2aXN1YWxpemFyIG7Dum1lcm8gZGUgVUNzIGFtb3N0cmFkYXMgZW0gY2FkYSBhbm8uICoqUG9yDQphZ29yYSBuw6NvIHByZWNpc2EqKiBTZSBkZXIgdGVtcG8gaW5jbHVpciBhbyBmaW5hbC4NCg0KYGBge3J9DQoNCmBgYA0KDQpgYGB7ciwgZWNobz1GQUxTRX0NCiMgZ2VyYXIgdGFiZWxhIGNvbSBvIG7Dum1lcm8gZGUgdW5pZGFkZXMgZGUgY29uc2VydmHDp8OjbyBhbW9zdHJhZGFzIGVtIGNhZGEgYW5vDQpuX3Vjc19hbm8gPC0gY29udGFyX25fdWNfYW5vKCkNCm5fdWNzX2Fubw0KYGBgDQoNCkdlcmFyIGZ1bsOnw6NvIHBhcmEgdGFiZWxhIGRpbsOibWljYS4NCg0KYGBge3J9DQpnZXJhcl90YWJkaW5fbl91Y19hbm8oKQ0KYGBgDQoNCiMjIyMgKipRdWFpcyB1bmlkYWRlcyBkZSBjb25zZXJ2YcOnw6NvIGZvcmFtIGFtb3N0cmFkYXMgZW0gdW0gbWFpb3IgbsO6bWVybyBkZSBhbm9zPyoqDQoNCkdlcmFyIGdyw6FmaWNvIGNvbSBvIG7Dum1lcm8gZGUgYW5vcyBlbSBxdWUgY2FkYSBVQyBmb2kgYW1vc3RyYWRhLiAqKlBvcg0KYWdvcmEgbsOjbyBwcmVjaXNhKiogU2Ugc29icmFyIHRlbXBvIGFjcmVzY2VudGFyIGFvIGZpbmFsLg0KDQpgYGB7cn0NCg0KYGBgDQoNClRhYmVsYQ0KDQpgYGB7cn0NCm5fYW5vX3VjIDwtIGNvbnRhcl9uX2Fub191YygpDQpuX2Fub191YyAgDQpgYGANCg0KR2VyYXIgdGFiZWxhIGRpbmFtaWNhLg0KDQpgYGB7cn0NCmdlcmFyX3RhYmRpbl9uX2Fub191YygpDQpgYGANCg0KIyMjIyAqKlF1YW50YXMgb2JzZXJ2YcOnw7VlcyBmb3JhbSByZWFsaXphZGFzIHBvciBVQyBlbSBjYWRhIGFubz8qKg0KDQpgYGB7cn0NCm5fb2JzX3VjX2FubyA8LSBjb250YXJfbl9vYnNfdWNfYW5vKCkNCm5fb2JzX3VjX2Fubw0KYGBgDQoNClRhYmVsYSBpbnRlcmF0aXZhIHBhcmEgY29uc3VsdGFyIHF1YW50YXMgb2JzZXJ2YcOnw7VlcyBmb3JhbSByZWFsaXphZGFzDQpwb3IgYW5vIGVtIGNhZGEgVUMNCg0KYGBge3J9DQpnZXJhcl90YWJkaW5fbl9vYnNfdWNfYW5vKCkNCmBgYA0KDQojIyMjICoqUXVhbnRhcyBvYnNlcnZhw6fDtWVzIHBhcmEgY2FkYSBlc3DDqWNpZXMgcG9yIGFubz8qKg0KDQpgYGB7cn0NCm5fb2JzX3NwX2FubyA8LSBjb250YXJfbl9vYnNfc3BfYW5vKCkNCm5fb2JzX3NwX2Fubw0KYGBgDQoNClRhYmVsYSBpbnRlcmF0aXZhIHBhcmEgY29uc3VsdGFyIHF1YW50YXMgb2JzZXJ2YcOnw7VlcyBmb3JhbSByZWFsaXphZGFzDQpwYXJhIGNhZGEgZXNww6ljaWUgZW0gY2FkYSBhbm8NCg0KYGBge3J9DQpnZXJhcl90YWJkaW5fbl9vYnNfc3BfYW5vKCkNCmBgYA0KDQojIyMjICoqUXVhbnRhcyBvYnNlcnZhw6fDtWVzIHBhcmEgY2FkYSBlc3DDqWNpZXMgcG9yIFVDIGUgcG9yIGFubz8qKg0KDQpgYGB7cn0NCm5fb2JzX3NwX3VjX2FubyA8LSBjb250YXJfbl9vYnNfc3BfdWNfYW5vKCkNCm5fb2JzX3NwX3VjX2Fubw0KYGBgDQoNClRhYmVsYSBpbnRlcmF0aXZhIHBhcmEgY29uc3VsdGFyIHF1YW50YXMgb2JzZXJ2YcOnw7VlcyBmb3JhbSByZWFsaXphZGFzDQpwYXJhIGNhZGEgZXNww6ljaWUgZW0gY2FkYSBhbm8NCg0KYGBge3J9DQpnZXJhcl90YWJkaW5fbl9vYnNfc3BfdWNfYW5vKCkNCmBgYA0KDQojIyMjICoqUXVhbnRhcyBvYnNlcnZhw6fDtWVzIHBhcmEgY2FkYSBlc3DDqWNpZXMgcG9yIFVDLCBwb3IgZXN0YcOnw6NvIGUgcG9yIGFubz8qKg0KDQpgYGB7cn0NCm5fb2JzX3NwX3VjX2VzdGFjYW9fYW5vIDwtIGNvbnRhcl9uX29ic19zcF91Y19lc3RhY2FvX2FubygpDQpuX29ic19zcF91Y19lc3RhY2FvX2Fubw0KYGBgDQoNCmBgYHtyfQ0KZ2VyYXJfdGFiZGluX25fb2JzX3NwX3VjX2VzdGFjYW9fYW5vKCkNCmBgYA0KDQojIyMjICoqQXZhbGlhbmRvIG7Dum1lcm8gZGUgcsOpcGxpY2FzIChFc3Rhw6fDtWVzIEFtb3N0cmFpcykgcG9yIFVDKioNCg0KIyMjIyAqKlNlbGVjaW9uYW5kbyBtZWxob3JlcyBtb2RlbG9zIGRlIGVzdHVkbyBjb25zaWRlcmFuZG8gZXN0cmF0aWZpY2HDp8OjbyBlc3BhY2lhbC90ZW1wb3JhbCAtLSBzZSBow6Egc3VmaWNpw6puY2lhIGFtb3N0cmFsICg2MC04MCBvYnNlcnZhw6fDtWVzKSBwb3IgZXN0cmF0byoqDQoNCi0gICBQb3Nzw612ZWlzIGVzdHJhdGlmaWNhw6fDtWVzIGVzcGFjaWFpcyAtLSBFQXMvVUNzDQoNCiAgICBgYGAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgICAtIFVDcy9Fc3DDqWNpZXMNCiAgICBgYGANCg0KICAgIC0gICBQb3Nzw612ZWlzIGVzdHJhdGlmaWNhw6fDtWVzIHRlbXBvcmFpcyAtLSBFc3DDqWNpZS9VQy9Bbm8NCg0KIyMjIyAqKkF2YWxpYW5kbyBkaXN0w6JuY2lhIGRlIHRydW5jYW1lbnRvKioNCg0KLSAgIEdyw6FmaWNvcyBkZSBkaXN0cmlidWnDp8OjbyBkYXMgZnJlcXXDqm5jaWFzIGRlIG9jb3Jyw6puY2lhIHggZGlzdMOibmNpYQ0KICAgIHBlcnBlbmRpY3VsYXIuIEFycXVpdm9zIGdyw6FmaWNvLWV4cGxvcmF0b3JpbzEuUm1kIGUNCiAgICBncsOhZmljby1leHBsb3JhdG9yaW8yLlJtZCAoZXUgbsOjbyBzZWkgY29tbyB2b2PDqiBmZXogcGFyYSBpbmNsdWlyDQogICAgYXF1ZWxhIGxpbmhhIHZlcm1lbGhhIGNvbSBvIHZhbG9yIGRlIHcgbm8gZ3LDoWZpY28gZXhwbG9yYXTDs3JpbyAyLA0KICAgIG1hcyBmaWNvdSBsZWdhbCkNCg0KIyMjIyAqKkRpc3RyaWJ1acOnw6NvIGRlIGRpc3TDom5jaWFzKioNCg0KYGBge3IgZGlzdHJpYnVpY2FvX2RzaXRhbmNpYSwgd2FybmluZz1GQUxTRX0NCiMgZ2VyYXIgbyBncsOhZmljbyBleHBsb3JhdMOzcmlvIGRhIGRpc3RyaWJ1acOnw6NvIGRlIGRpc3TDom5jaWFzIHBlcnBlbmRpY3VsYXJlcyBwYXJhIGEgZXNww6ljaWVzIERhc3lyb2N0YSBjcm9jb25vdGEgbmEgUmVzZXggVGFwYWrDs3MtQXJhcGl1bnMNCmZpZyA8LSBkYWRvc19maWx0cmFkb3MgfD4NCiAgIyBleGNsdWlyIE5BJ3MgZGEgdmFyacOhdmVsIGRpc3RhbmNlDQogIHRpZHlyOjpkcm9wX25hKGRpc3RhbmNlKSB8PiANCiAgcGxvdGFyX2Rpc3RyaWJ1aWNhb19kaXN0YW5jaWFfaW50ZXJhdGl2bygpDQoNCmZpZw0KYGBgDQoNCiMjIyMgKipBdmFsaWFuZG8gY292YXJpw6F2ZWlzKioNCg0KLS0gQXMgY292YXJpw6F2ZWlzIGRldmVtIHNlciBwZW5zYWRhcyBkZSBhY29yZG8gY29tIG8gZ3J1cG8gdGF4b27DtG1pY28uDQpFc3DDqWNpZXMgcXVlIGZvcm1hbSBncnVwb3MgZGV2ZW0gdGVyIGEgY292YXJpw6F2ZWwgJ3NpemUnLg0KDQpBcyBlc3RyYXTDqWdpYXMgZGUgZXN0cmF0aWZpY2HDp8OjbyBwb2RlbSBzZXIgc3Vic3RpdHXDrWRhcyBwb3IgY292YXJpw6F2ZWlzDQp0YW1iw6ltIChlc3RyYXRvcyBlc3BhY2lhaXMvIGFubykNCg0KQ29tbyBjb3ZhcmnDoXZlbCB0ZW1wb3JhbCwgcG9kZSBzZSBwZW5zYXIgZW0gdXNhciwgYWzDqW0gZG8gYW5vLCBhIGVzdGHDp8Ojbw0KZG8gYW5vIChzZWFzb24pLCBvIGhvcsOhcmlvIGRvIGRpYSAocGFyYSBhbmltYWlzIHF1ZSB2YXJpYW0gYSBhdGl2aWRhZGUpLg0KTyBob3LDoXJpbyBkbyBkaWEgcG9kZSBzZXIgY29udmVydGlkbyBlbSB0ZW1wbyBhcMOzcyBuYXNjZXIgZG8gc29sIChjb21vDQpubyBleGVtcGxvKS4gTWFzIHBhcmEgaXNzbyDDqSBuZWNlc3PDoXJpbyBjcmlhciBlc3NhIHZhcmnDoXZlbCBubyBkYXRhc2V0Lg0KRSBuw6NvIMOpIHRyaXZpYWwgcG9ycXVlIHByZWNpc2Egc2FiZXIgbyBob3LDoXJpbyBkZSBuYXNjZXIgZG8gc29sIGVtIGNhZGENCmRpYS9sb2NhbCBwYXJhIGNhbGN1bGFyLg0KDQoqKkFURU7Dh8ODTzogZ2VyYXIgZ3LDoWZpY29zIGRpc3TDom5jaWEgeCBjb3ZhcmnDoXZlbCoqDQoNCkV4ZW1wbG8gZGUgR3LDoWZpY29zIGRlIE1hcnF1ZXMgZXQgYWwuIDIwMDcNCg0KIyAqKlBBUlRFIFYgLS0gQWp1c3RhbmRvIG9zIG1vZGVsb3MqKg0KDQpFc3NlIHRyYWJhbGhvIGRvIE1hcnF1ZSBldCBhbC4gMjAwNyDDqSB1bWEgYm9hIHJlZmVyw6puY2lhIGRlIGNvbW8gdXNhciBhcw0KYWJvcmRhZ2VucyBDRFMgZ2xvYmFsLCBDRFMgZXN0cmF0aWZpY2FkYSBlIE1DRFMuDQoNCkFxdWksIMOpIHBvc3PDrXZlbCB0ZXN0YXIgYWxndW5zIGNhbWluaG9zIGRlIG1vZGVsb3MuIEEgZXN0cmF0aWZpY2HDp8OjbyBzw7MNCmZheiBzZW50aWRvIHF1YW5kbyBvIHZvbHVtZSBkZSBkYWRvcyBmb3IgZ3JhbmRlLiBBaW5kYSBhc3NpbSBvIHVzbyBkZQ0KY292YXJpw6F2ZWlzIHBvZGUgc3Vic3RpdHVpciBhIGVzdHJhdGlmaWNhw6fDo28uIFBlbnNhciBlbSBjb21vIG9yaWVudGFyIG8NCnVzbyBkZXNzYXMgYWJvcmRhZ2Vucw0KDQojIyAqKk1vZGVsb3MgcGVsYSBhYm9yZGFnZW0gQ0RTIC0tIGRhZG9zIGdsb2JhaXMqKg0KDQotICAgZnVuw6fDo28gZHMgZG8gRGlzdGFuY2UgKGFyZ3VtZW50b3MgYsOhc2ljb3M6IHRydW5jYXRpb247IGtleSwNCiAgICBhZGp1c3RtZW50LCBzY2FsZS4uLiBlc3R1ZGFyIGFyZ3VtZW50b3MgcGFyYSB2ZXIgc2UgbWFpcyBhbGd1bQ0KICAgIGludGVyZXNzYSkNCg0KIyMgKipNb2RlbG9zIHBlbGEgYWJvcmRhZ2VtIENEUyAtLSBkYWRvcyBlc3RyYXRpZmljYWRvcyoqDQoNCi0gICBBcXVpIHByZWNpc2EgdmVyIGRpcmVpdGluaG8gb3MgY3VpZGFkb3MgcXVlIHByZWNpc2EgdGVyIHBhcmEgYWp1c3Rhcg0KICAgIGFzIGZ1bsOnw7VlcyBub3MgZGFkb3MgZXN0cmF0aWZpY2Fkb3MuIEFjaG8gcXVlIGZheiBlbSBibG9jb3MuIFZhaQ0KICAgIGFwbGljYW5kbyBvcyBtZXNtb3MgcGFyw6JtZXRyb3MgcGFyYSB0b2RvcyBvcyBlc3RyYXRvcyBhIGNhZGEgbW9kZWxvLg0KDQotICAgcGFyYSBjYWRhIGVzdHJhdG8gKGVzcGFjaWFsIG91IHRlbXBvcmFsKSB1c2FyIC0gZnVuw6fDo28gZHMgZG8NCiAgICBEaXN0YW5jZSAoYXJndW1lbnRvcyBiw6FzaWNvczogdHJ1bmNhdGlvbjsga2V5LCBhZGp1c3RtZW50LCBzY2FsZS4uLg0KICAgIGVzdHVkYXIgYXJndW1lbnRvcyBwYXJhIHZlciBzZSBtYWlzIGFsZ3VtIGludGVyZXNzYSkNCg0KIyMgKipNb2RlbG9zIHBlbGEgYWJvcmRhZ2VtIE1DRFMgLS0gZGFkb3MgZ2xvYmFpcyoqDQoNCkFxdWkgbsOjbyBmYXogc2VudGlkbyBlc3RyYXRpZmljYXINCg0KLSAgIGZ1bsOnw6NvIGRzIGRvIERpc3RhbmNlIChhcmd1bWVudG9zIGLDoXNpY29zOiB0cnVuY2F0aW9uOyBrZXksDQogICAgYWRqdXN0bWVudCwgc2NhbGUuLi4gZXN0dWRhciBhcmd1bWVudG9zIHBhcmEgdmVyIHNlIG1haXMgYWxndW0NCiAgICBpbnRlcmVzc2EuLi4gcGFyYSBhcyBjb3ZhcmnDoXZlaXMgZW50cmEgbyBhcmd1bWVudG8gZm9ybXVsYSkNCg0KRGljYXMgZW0gTWlsbGVyIGV0IGFsLiAyMDE5IHNvYnJlIGNvdmFyacOhdmVpcyAodmVyIGFycXVpdm8gbm8gZHJpdmVyKS4NCg0KIyAqKlBBUlRFIFZJIC0tIEF2YWxpYW5kbyBvcyBtb2RlbG9zKioNCg0KIyMgKipBanVzdGUgZG9zIG1vZGVsb3MqKg0KDQotICAgZnVuw6fDo28gZ29mX2RzDQoNCi0tIHBhcmEgZ2VyYXIgUS1RIHBsb3RzIGUgdGVzdGVzIGFzc29jaWFkb3MNCg0KIyMgKipTZWxlY2lvbmFuZG8gbW9kZWxvcyAoQUlDKSoqDQoNCi0tIGZ1bsOnw6NvIHN1bW1hcml6ZV9kc19tb2RlbHMNCg0KRElDQVMgRVhUUkFTIERFIE1JTExFUiBldCBhbC4gMjAxOQ0KDQojICoqUEFSVEUgVklJIC0tIFBST0RVVE8gRklOQUwqKg0KDQotICAgQ29tbyBvcmdhbml6YXINCg0KLSAgIEludGVyYXRpdmlkYWRlDQoNCioqQ3JpYXIgZXhwcmVzc8O1ZXMgcmVhdGl2YXMqKg0KDQpyZWFjdGl2ZSgpIGV2ZW50UmVhY3RpdmUoKQ0KDQpvYnNlcnZlKCkgb2JzZXJ2ZUV2ZW50KCkNCg0KcmVhY3RpdmVWYWwoKSByZWFjdGl2ZVZhbHVlcygpDQoNCmlzb2xhdGUoKQ0KDQotICAgZ2VyYXIgbyB0YWwgZG9jdW1lbnRvIGF1dG9tYXRpemFkbyBjb250ZW5kbyB0b2RvIGVzc2UgZmx1eG8gbWFpcyBvcw0KICAgIHJlc3VsdGFkb3MgZGFzIGFuw6FsaXNlczsNCg0KLSAgIHRlbnRhciB0cmFuc2Zvcm1hciBpc3NvIG51bSBkYXNoYm9hcmQvYXBsaWNhdGl2byDDum5pY28gaW50ZWdyYW5kbw0KICAgIGNhZGEgZXRhcGEgZGVzc2EgbnVtYSBkYXMgYWJhcyBkbyBkYXNoYm9hcmQNCg0KLSAgIFBhY290ZSB0YXJnZXRzIHNlcmlhIMO6bHRpbD8NCg0KIyAqKkdsb3Nzw6FyaW8qKg0KDQpEZXNjcmV2ZXIgYXMgdmFyacOhdmVpcyAoY29sdW5hcyksIHRlcm1vcyB0w6ljbmljb3MgYW8gbG9uZ28gZG8gdGV4dG8uLi4NCg0KLSAgIGBFZmZvcnRgIC0gZXh0ZW5zw6NvIHRvdGFsIHBlcmNvcnJpZGEgZW0gbWV0cm9zIG5vIGNvbmp1bnRvIGRlIGRhZG9zDQogICAgc2VsZWNpb2RvLg0KDQotICAgDQo=